<?php

namespace App\Http\Controllers\Dashboard\Admin;

use Carbon\Carbon;
use App\Models\User;
use App\Models\Transaction;
use App\Models\Notification;
use Illuminate\Http\Request;
use App\Enum\TransactionType;
use App\Enum\TransactionStatus;
use App\Enum\TransactionDirection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreTransactionRecordRequest;

class UserTransactionRecordController extends Controller
{
    public function create(string $uuid)
    {
        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('admin.dashboard')],
            ['label' => 'Users', 'url' => route('admin.user.index')],
            ['label' => 'Create Transaction Record', 'active' => true],
        ];

        $user = User::where('uuid', $uuid)->firstOrFail();

        $data = [
            'title' => 'Create Transaction Record',
            'breadcrumbs' => $breadcrumbs,
            'user' => $user,
            'transactionTypes' => TransactionType::cases(),
            'transactionDirections' => TransactionDirection::cases(),
        ];

        return view('dashboard.admin.user.transaction_record.create', $data);
    }

    // public function store(StoreTransactionRecordRequest $request, string $uuid)
    // {
    //     $user = User::where('uuid', $uuid)->firstOrFail();

    //     $start = Carbon::parse($request->start_date);
    //     $end = Carbon::parse($request->end_date);

    //     $dates = [];
    //     while ($start->lte($end)) {
    //         $dates[] = $start->copy();
    //         $start->addDay();
    //     }

    //     try {
    //         DB::beginTransaction();

    //         $initialBalance = $user->account_balance;

    //         foreach ($dates as $date) {
    //             $amounts = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000];

    //             $amount = $amounts[array_rand($amounts)];

    //             if ($request->direction == 'credit') {
    //                 if ($user->exceedsAccountCapacity($amount)) {
    //                     DB::rollBack();
    //                     return redirect()->back()->with('error', 'This account cannot hold more than ' . currency($user->currency) . number_format($user->account_limit));
    //                 }
    //             }

    //             switch ($request->direction) {
    //                 case 'debit':
    //                     if ($initialBalance < $amount) {
    //                         DB::rollBack();
    //                         return redirect()->back()->with('error', 'Insufficient balance!');
    //                     }

    //                     $initialBalance -= $amount;
    //                     break;

    //                 case 'credit':
    //                     $initialBalance += $amount;
    //                     break;
    //             }

    //             Transaction::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'type' => $request->type,
    //                 'direction' => $request->direction,
    //                 'description' => $request->description
    //                     ?? ucfirst($request->direction) . " of " . currency($user->currency) . formatAmount($amount) . " via " . ucfirst($request->type),
    //                 'amount' => $amount,
    //                 'current_balance' => $initialBalance,
    //                 'transaction_at' => $date,
    //                 'reference_id' => generateReferenceId(),
    //                 'status' => TransactionStatus::Completed->value
    //             ]);

    //             $message = match ($request->direction) {
    //                 'credit' => "Your account has been credited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$request->type} on " . formatDateTime($date) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",

    //                 'debit' => "Your account has been debited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$request->type} on " . formatDateTime($date) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",
    //             };


    //             Notification::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'title' => $request->type,
    //                 'description' => $message,
    //             ]);
    //         }

    //         $user->account_balance = $initialBalance;
    //         $user->save();

    //         DB::commit();

    //         return redirect()->route('admin.user.transaction_record.create', [$user->uuid])->with('success', 'Transaction record created successfully!');
    //     } catch (\Exception $e) {
    //         DB::rollBack();
    //         Log::error($e->getMessage());
    //         return redirect()->back()->with('error', config('app.messages.error'));
    //     }
    // }
    // public function store(StoreTransactionRecordRequest $request, string $uuid)
    // {
    //     $user = User::where('uuid', $uuid)->firstOrFail();

    //     $start = Carbon::parse($request->start_date)->startOfMinute();
    //     $end = Carbon::parse($request->end_date)->startOfMinute();

    //     $interval = 6; // hours between transactions

    //     try {
    //         DB::beginTransaction();

    //         $initialBalance = $user->account_balance;
    //         $amounts = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000];

    //         // Loop through the selected datetime range
    //         while ($start->lte($end)) {
    //             $amount = $amounts[array_rand($amounts)];

    //             if ($request->direction === 'credit') {
    //                 if ($user->exceedsAccountCapacity($amount)) {
    //                     DB::rollBack();
    //                     return back()->with('error', 'This account cannot hold more than ' . currency($user->currency) . number_format($user->account_limit));
    //                 }
    //                 $initialBalance += $amount;
    //             } elseif ($request->direction === 'debit') {
    //                 if ($initialBalance < $amount) {
    //                     DB::rollBack();
    //                     return back()->with('error', 'Insufficient balance!');
    //                 }
    //                 $initialBalance -= $amount;
    //             }

    //             // Create the transaction record
    //             Transaction::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'type' => $request->type,
    //                 'direction' => $request->direction,
    //                 'description' => $request->description
    //                     ?? ucfirst($request->direction) . " of " . currency($user->currency) . formatAmount($amount) . " via " . ucfirst($request->type),
    //                 'amount' => $amount,
    //                 'current_balance' => $initialBalance,
    //                 'transaction_at' => $start,
    //                 'reference_id' => generateReferenceId(),
    //                 'status' => TransactionStatus::Completed->value
    //             ]);

    //             // Add notification
    //             $message = match ($request->direction) {
    //                 'credit' => "Your account has been credited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$request->type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",

    //                 'debit' => "Your account has been debited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$request->type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",
    //             };

    //             Notification::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'title' => ucfirst($request->type),
    //                 'description' => $message,
    //             ]);

    //             // Move to next time interval
    //             $start->addHours($interval);
    //         }

    //         $user->account_balance = $initialBalance;
    //         $user->save();

    //         DB::commit();

    //         return redirect()->route('admin.user.transaction_record.create', [$user->uuid])
    //             ->with('success', 'Transaction record created successfully!');
    //     } catch (\Exception $e) {
    //         DB::rollBack();
    //         Log::error($e->getMessage());
    //         return back()->with('error', config('app.messages.error'));
    //     }
    // }

    // public function store(StoreTransactionRecordRequest $request, string $uuid)
    // {
    //     // Full Code (with random debit/credit generation)

    //     $user = User::where('uuid', $uuid)->firstOrFail();

    //     $start = Carbon::parse($request->start_date)->startOfMinute();
    //     $end = Carbon::parse($request->end_date)->startOfMinute();

    //     $interval = 6; // hours between transactions

    //     try {
    //         DB::beginTransaction();

    //         $initialBalance = $user->account_balance;
    //         $amounts = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000];
    //         $types = ['transfer', 'deposit'];

    //         while ($start->lte($end)) {
    //             // Randomize direction and type
    //             $direction = collect(['credit', 'debit'])->random();
    //             $type = collect($types)->random();
    //             $amount = collect($amounts)->random();

    //             // Handle credit/debit balance logic
    //             if ($direction === 'credit') {
    //                 if ($user->exceedsAccountCapacity($amount)) {
    //                     DB::rollBack();
    //                     return back()->with('error', 'This account cannot hold more than ' . currency($user->currency) . number_format($user->account_limit));
    //                 }
    //                 $initialBalance += $amount;
    //             } else {
    //                 if ($initialBalance < $amount) {
    //                     // If not enough balance, skip this debit
    //                     $start->addHours($interval);
    //                     continue;
    //                 }
    //                 $initialBalance -= $amount;
    //             }

    //             // Create transaction
    //             $transaction = Transaction::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'type' => $type,
    //                 'direction' => $direction,
    //                 'description' => ucfirst($direction) . " of " . currency($user->currency) . formatAmount($amount) . " via " . ucfirst($type),
    //                 'amount' => $amount,
    //                 'current_balance' => $initialBalance,
    //                 'transaction_at' => $start,
    //                 'reference_id' => generateReferenceId(),
    //                 'status' => TransactionStatus::Completed->value,
    //             ]);

    //             // Generate message
    //             $message = match ($direction) {
    //                 'credit' => "Your account has been credited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",

    //                 'debit' => "Your account has been debited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",
    //             };

    //             // Create notification
    //             Notification::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'title' => ucfirst($type),
    //                 'description' => $message,
    //             ]);

    //             // Move to next date interval
    //             $start->addHours($interval);
    //         }

    //         $user->account_balance = $initialBalance;
    //         $user->save();

    //         DB::commit();

    //         return redirect()->route('admin.user.transaction_record.create', [$user->uuid])
    //             ->with('success', 'Random transaction records created successfully!');
    //     } catch (\Exception $e) {
    //         DB::rollBack();
    //         Log::error($e->getMessage());
    //         return back()->with('error', config('app.messages.error'));
    //     }
    // }

    // public function store(StoreTransactionRecordRequest $request, string $uuid)
    // {
    //     // Realistic Auto-Generated Transactions (random intervals, direction, amount, type)

    //     $user = User::where('uuid', $uuid)->firstOrFail();

    //     $start = Carbon::parse($request->start_date)->startOfMinute();
    //     $end = Carbon::parse($request->end_date)->startOfMinute();

    //     try {
    //         DB::beginTransaction();

    //         $initialBalance = $user->account_balance;
    //         $amounts = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000];
    //         $types = ['transfer', 'deposit'];

    //         while ($start->lte($end)) {
    //             // Randomize interval between 1 and 8 hours
    //             $interval = rand(1, 8);

    //             // Randomize transaction direction and type
    //             $direction = collect(['credit', 'debit'])->random();
    //             $type = collect($types)->random();
    //             $amount = collect($amounts)->random();

    //             // Balance and capacity validation
    //             if ($direction === 'credit') {
    //                 if ($user->exceedsAccountCapacity($amount)) {
    //                     DB::rollBack();
    //                     return back()->with('error', 'This account cannot hold more than ' . currency($user->currency) . number_format($user->account_limit));
    //                 }
    //                 $initialBalance += $amount;
    //             } else {
    //                 if ($initialBalance < $amount) {
    //                     // Skip this debit if balance is too low
    //                     $start->addHours($interval);
    //                     continue;
    //                 }
    //                 $initialBalance -= $amount;
    //             }

    //             // Create transaction record
    //             Transaction::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'type' => $type,
    //                 'direction' => $direction,
    //                 'description' => ucfirst($direction) . " of " . currency($user->currency) . formatAmount($amount) . " via " . ucfirst($type),
    //                 'amount' => $amount,
    //                 'current_balance' => $initialBalance,
    //                 'transaction_at' => $start,
    //                 'reference_id' => generateReferenceId(),
    //                 'status' => TransactionStatus::Completed->value,
    //             ]);

    //             // Send notification
    //             $message = match ($direction) {
    //                 'credit' => "Your account has been credited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",

    //                 'debit' => "Your account has been debited with " . currency($user->currency) . formatAmount($amount) .
    //                     " for {$type} on " . formatDateTime($start) .
    //                     ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",
    //             };

    //             Notification::create([
    //                 'uuid' => str()->uuid(),
    //                 'user_id' => $user->id,
    //                 'title' => ucfirst($type),
    //                 'description' => $message,
    //             ]);

    //             // Move to next random time
    //             $start->addHours($interval)->addMinutes(rand(10, 59));
    //         }

    //         $user->account_balance = $initialBalance;
    //         $user->save();

    //         DB::commit();

    //         return redirect()
    //             ->route('admin.user.transaction_record.create', [$user->uuid])
    //             ->with('success', 'Randomized transaction history created successfully!');
    //     } catch (\Exception $e) {
    //         DB::rollBack();
    //         Log::error($e->getMessage());
    //         return back()->with('error', config('app.messages.error'));
    //     }
    // }

    public function store(StoreTransactionRecordRequest $request, string $uuid)
    {
        // Final Version — Realistic Banking History Generator

        $user = User::where('uuid', $uuid)->firstOrFail();

        $start = Carbon::parse($request->start_date)->startOfMinute();
        $end = Carbon::parse($request->end_date)->startOfMinute();

        try {
            DB::beginTransaction();

            $initialBalance = $user->account_balance;
            $amounts = [5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000];

            while ($start->lte($end)) {
                // Randomize interval between 1–8 hours
                $interval = rand(1, 8);

                // Weighted random direction: 70% credit, 30% debit
                $direction = rand(1, 100) <= 70 ? 'credit' : 'debit';

                // Force type based on direction
                $type = $direction === 'credit' ? 'deposit' : 'transfer';

                // Random amount
                $amount = collect($amounts)->random();

                // Handle balance logic
                if ($direction === 'credit') {
                    if ($user->exceedsAccountCapacity($amount)) {
                        DB::rollBack();
                        return back()->with('error', 'This account cannot hold more than ' . currency($user->currency) . number_format($user->account_limit));
                    }
                    $initialBalance += $amount;
                } else {
                    if ($initialBalance < $amount) {
                        // Skip if insufficient balance
                        $start->addHours($interval)->addMinutes(rand(10, 59));
                        continue;
                    }
                    $initialBalance -= $amount;
                }

                // Create transaction record
                Transaction::create([
                    'uuid' => str()->uuid(),
                    'user_id' => $user->id,
                    'type' => $type,
                    'direction' => $direction,
                    'description' => ucfirst($direction) . " of " . currency($user->currency) . formatAmount($amount) . " via " . ucfirst($type),
                    'amount' => $amount,
                    'current_balance' => $initialBalance,
                    'transaction_at' => $start,
                    'reference_id' => generateReferenceId(),
                    'status' => TransactionStatus::Completed->value,
                ]);

                // Notification message
                $message = match ($direction) {
                    'credit' => "Your account has been credited with " . currency($user->currency) . formatAmount($amount) .
                        " for {$type} on " . formatDateTime($start) .
                        ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",

                    'debit' => "Your account has been debited with " . currency($user->currency) . formatAmount($amount) .
                        " for {$type} on " . formatDateTime($start) .
                        ". Your new balance is " . currency($user->currency) . formatAmount($initialBalance) . ".",
                };

                Notification::create([
                    'uuid' => str()->uuid(),
                    'user_id' => $user->id,
                    'title' => ucfirst($type),
                    'description' => $message,
                ]);

                // Move forward by random hours and minutes
                $start->addHours($interval)->addMinutes(rand(10, 59));
            }

            // Save final balance
            $user->account_balance = $initialBalance;
            $user->save();

            DB::commit();

            return redirect()
                ->route('admin.user.transaction_record.create', [$user->uuid])
                ->with('success', config('app.messages.success'));
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error($e->getMessage());
            return back()->with('error', config('app.messages.error'));
        }
    }
}
