<?php

use App\Models\Account;
use App\Support\Currency;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Support\Collection;


new class extends Component {
    // =============================
    // Account Totals
    // =============================
    public $totalDeposits = 0;
    public $totalExpenses = 0;
    public $totalWalletBalance = 0;
    public $reservedWalletBalance = 0;
    public $availableWalletBalance = 0;

    // =============================
    // Accounts and Focus
    // =============================
    /** @var Collection<int, Account> */
    public Collection $accounts;
    public array $bankAccountTypes = [];
    public ?string $bank_account_type = null;
    private ?Account $focusedAccountCache = null;
    public $currentBankAccountType;
    public array $existingAccountTypes = [];

    // Multiple active accounts allowed
    public $focusedAccountId; // The account selected for calculations
    public $focusedIndex;     // Index of focused account
    public $focusedAccountUpdated;

    // =============================
    // Filter and Profile
    // =============================
    public $filter = 'all';
    public $profileId;

    public $latestTransactions = [];
    public array $summaryStats = [];
    public array $healthStats = [];
    public $unreadAlerts;
    public string $healthPeriod = 'daily';
    public bool $monthlyAvailable = true;
    public $currencySymbol;
    public $userCryptoBalances; // AccountCryptoBalance collection

    // =============================
    // Mount component
    // =============================
    public function mount()
    {
        $user = auth()->user();

        if (!$user->profile) {
            abort(404, 'Profile not found.');
        }

        $profile = $user->profile;
        $this->profileId = $profile->id;

        // Fetch all accounts for this profile
        $this->accounts = Account::where('profile_id', $this->profileId)->get();

        // Determine focused account using profile's stored focused_account_id
        $focused = $profile->focusedAccount;

        // Fallback to first active account if none stored
        if (!$focused) {
            $focused = $this->accounts->firstWhere('is_active', true);
        }

        // Fallback to first account if still none
        if (!$focused && $this->accounts->isNotEmpty()) {
            $first = $this->accounts->first();
            $first->update(['is_active' => true]);
            $focused = $first;
        }

        // Set Livewire properties
        $this->focusedAccountId = $focused?->id;
        $this->focusedIndex = $this->accounts->values()->search(fn($a) => $a->id === $this->focusedAccountId);

        // Update totals, balances, stats for focused account
        $this->updateFocusedAccountProperties();

        // Prepare bank account types for modal
        $this->bankAccountTypes = collect(config('bank.account_types'))
            ->map(fn($v, $k) => ['value' => $k, 'label' => "{$v['emoji']} {$v['label']}"])
            ->values()
            ->toArray();

        $this->bank_account_type = '';
        $this->existingAccountTypes = $this->accounts->pluck('bank_account_type')->toArray();

        $this->currencySymbol = Currency::symbol($profile->currency);
        // Load user crypto balances
        $this->userCryptoBalances = $user->profile?->accounts()->with('cryptoBalances')->get()
            ->pluck('cryptoBalances')->flatten() ?? collect([]);
        $this->updateUnreadAlerts();
    }



    private function getFocusedAccount(): ?Account
    {
        return $this->focusedAccountCache
            ??= $this->accounts->firstWhere('id', $this->focusedAccountId)
            ?? Account::find($this->focusedAccountId);
    }
    // =============================
    // Computed properties
    // =============================
    #[Computed]
    public function creditCards()
    {
        return auth()->user()
            ->creditCards() // Relationship from User model
            ->orderBy('created_at', 'desc')
            ->get();
    }

    #[Computed]
    public function focusedCards()
    {
        $account = $this->getFocusedAccount();

        if (!$account) {
            return [
                'loan' => null,
                'grant' => null,
                'tax_refund' => null,
            ];
        }

        return [
            'loan' => Transaction::where('account_id', $account->id)
                ->where('type', 'loan')
                ->latest()
                ->first(),
            'grant' => Transaction::where('account_id', $account->id)
                ->where('type', 'grant')
                ->latest()
                ->first(),
            'tax_refund' => Transaction::where('account_id', $account->id)
                ->where('type', 'tax_refund')
                ->latest()
                ->first(),
        ];
    }

    #[Computed]
    public function recentBeneficiaries()
    {
        return auth()->user()
            ->beneficiaries() // assuming a relationship in User model
            ->latest()        // order by created_at descending
            ->take(6)         // limit to 6
            ->get();
    }

    // =============================
    // Update filter
    // =============================
    public function updateFilter($filter)
    {
        $this->filter = $filter;
        $this->updateFocusedAccountProperties(); // Recalculate totals and stats
    }

    // =============================
    // Update focused account data
    // =============================
    private function updateFocusedAccountProperties()
    {
        $this->focusedAccountCache = null;
        $account = $this->getFocusedAccount();

        if (!$account)
            return;

        $this->currentBankAccountType = $account->bank_account_type;
        $balances = $account->dashboard_balances;
        $this->totalWalletBalance = $balances['total'];
        $this->reservedWalletBalance = $balances['reserved'];
        $this->availableWalletBalance = $balances['available'];
        $this->focusedAccountUpdated = $account->updated_at?->diffForHumans();

        $this->calculateTotals();
        $this->updateLatestTransactions();
        $this->buildStats();
    }

    // =============================
    // Calculate totals for focused account
    // =============================
    private function calculateTotals()
    {
        $account = $this->getFocusedAccount();

        if (!$account) {
            $this->totalDeposits = $this->totalExpenses = 0;
            return;
        }

        $baseQuery = Transaction::where('account_id', $account->id);
        $baseQuery = $this->applyFilterToQuery($baseQuery);

        $this->totalDeposits = (clone $baseQuery)
            ->incoming()
            ->sum('amount');

        $this->totalExpenses = (clone $baseQuery)
            ->outgoing()
            ->sum('amount');

    }

    // =============================
    // Build summary and health stats
    // =============================
    private function buildStats()
    {
        $account = $this->getFocusedAccount();

        if (!$account) {
            $this->summaryStats = [];
            $this->healthStats = [];
            return;
        }

        $baseQuery = Transaction::where('account_id', $account->id);

        // Daily and monthly usage
        $dailyUsed = (clone $baseQuery)
            ->outgoing()
            ->whereDate('created_at', Carbon::today())
            ->sum('amount');

        $monthlyUsed = (clone $baseQuery)
            ->outgoing()
            ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
            ->sum('amount');


        $dailyLimit = $account->daily_transaction_limit;
        $monthlyLimit = $account->monthly_transaction_limit;

        $dailyRemaining = max(0, $dailyLimit - $dailyUsed);
        $monthlyRemaining = max(0, $monthlyLimit - $monthlyUsed);

        $dailyProgress = $dailyLimit ? min(100, ($dailyUsed / $dailyLimit) * 100) : 0;
        $monthlyProgress = $monthlyLimit ? min(100, ($monthlyUsed / $monthlyLimit) * 100) : 0;

        // Filtered transactions for reporting
        $filteredQuery = $this->applyFilterToQuery(clone $baseQuery);
        $totalTransactions = (clone $filteredQuery)->count();

        // Spending trends
        $currentMonthExpenses = (clone $baseQuery)
            ->outgoing()
            ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
            ->sum('amount');

        $lastMonthExpenses = (clone $baseQuery)
            ->outgoing()
            ->whereBetween('created_at', [
                Carbon::now()->subMonth()->startOfMonth(),
                Carbon::now()->subMonth()->endOfMonth()
            ])
            ->sum('amount');

        $monthlyIncome = (clone $baseQuery)
            ->incoming()
            ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
            ->sum('amount');


        $totalDays = Carbon::now()->daysInMonth;
        $activeDays = Transaction::where('account_id', $account->id)
            ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
            ->distinct()
            ->count(DB::raw('DATE(created_at)'));

        $consistencyPercent = min(100, ($activeDays / $totalDays) * 100);


        if ($currentMonthExpenses == 0 && $lastMonthExpenses == 0) {
            $trendLabel = 'No Activity';
            $trendColor = 'gray';
            $trendProgress = 0;
        } elseif ($currentMonthExpenses > $lastMonthExpenses) {
            $trendLabel = 'Increasing';
            $trendColor = 'yellow';
            $trendProgress = min(100, ($currentMonthExpenses / max(1, $lastMonthExpenses)) * 100);
        } elseif ($currentMonthExpenses < $lastMonthExpenses) {
            $trendLabel = 'Decreasing';
            $trendColor = 'green';
            $trendProgress = 100 - min(100, ($currentMonthExpenses / max(1, $lastMonthExpenses)) * 100);
        } else {
            $trendLabel = 'Stable';
            $trendColor = 'blue';
            $trendProgress = 50;
        }

        // Summary cards
        $this->summaryStats = [
            [
                'label' => 'DAILY LIMIT REMAINING',
                'value' => number_format($dailyRemaining, 2),
                'has_symbol' => true,
                'description' => 'Available today',
                'icon' => 'globe-asia-australia',
                'icon_bg' => 'bg-indigo-600',
                'progress' => $dailyProgress,
            ],
            [
                'label' => 'TOTAL TRANSACTIONS',
                'value' => number_format($totalTransactions),
                'has_symbol' => false,
                'description' => 'Transactions in selected period',
                'icon' => 'arrow-top-right-on-square',
                'icon_bg' => 'bg-red-600',
            ],
            [
                'label' => 'TOTAL SPEND',
                'value' => number_format($currentMonthExpenses, 2),
                'has_symbol' => true,
                'description' => 'Expenses in selected period',
                'icon' => 'currency-dollar',
                'icon_bg' => 'bg-green-600',
            ],
        ];

        // Health stats
        $this->healthStats = [
            'account_health' => [
                'daily' => [
                    'used' => $dailyUsed,
                    'limit' => $dailyLimit,
                    'remaining' => $dailyRemaining,
                    'progress' => $dailyProgress,
                ],
                'monthly' => [
                    'used' => $monthlyUsed,
                    'limit' => $monthlyLimit,
                    'remaining' => $monthlyRemaining,
                    'progress' => $monthlyProgress,
                ],
            ],
            'spending_trends' => [
                'value' => $currentMonthExpenses,
                'label' => $trendLabel,
                'color' => $trendColor,
                'progress' => $trendProgress,
            ],
            'activity_consistency' => [
                'active_days' => $activeDays,
                'total_days' => $totalDays,
                'percent' => $consistencyPercent,
            ]
            ,
            'total_transactions' => $totalTransactions,
        ];
    }

    // =============================
    // Latest transactions for focused account
    // =============================
    private function updateLatestTransactions()
    {
        $account = $this->getFocusedAccount();

        if (!$account) {
            $this->latestTransactions = [];
            return;
        }

        $query = Transaction::where('account_id', $account->id);
        $query = $this->applyFilterToQuery($query);

        $this->latestTransactions = $query->latest()
            ->take(3)
            ->get();
    }

    // =============================
    // Apply filter to query
    // =============================
    private function applyFilterToQuery($query)
    {
        switch ($this->filter) {
            case 'yesterday':
                $query->whereDate('created_at', Carbon::yesterday());
                break;

            case 'this_week':
                $query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]);
                break;

            case 'last_week':
                $query->whereBetween('created_at', [Carbon::now()->subWeek()->startOfWeek(), Carbon::now()->subWeek()->endOfWeek()]);
                break;

            case 'this_month':
                $query->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()]);
                break;

            case 'last_month':
                $query->whereBetween('created_at', [Carbon::now()->subMonth()->startOfMonth(), Carbon::now()->subMonth()->endOfMonth()]);
                break;

            case 'all':
            default:
                // No filter
                break;
        }

        return $query;
    }

    // =============================
// Toggle account and auto-focus
// =============================
    public function toggleAccountActive($accountId)
    {
        $account = $this->accounts->firstWhere('id', $accountId);
        $this->focusedAccountCache = null;

        if (!$account) {
            $this->addError('account', 'Account not found.');
            return;
        }

        $newState = !$account->is_active;

        // Prevent deactivating the last active account
        if (!$newState) {
            $activeAccountsCount = $this->accounts->where('is_active', true)->count();

            if ($activeAccountsCount <= 1 && $account->is_active) {
                $this->addError('account', 'Cannot deactivate the last active account.');
                $this->dispatch('showToast', message: 'Cannot deactivate the last active account.', type: 'error');
                return;
            }
        }

        // Toggle DB value
        $account->update(['is_active' => $newState]);

        // Update Livewire collection
        $this->accounts = $this->accounts->map(function ($a) use ($accountId, $newState) {
            if ($a->id === $accountId) {
                $a->is_active = $newState;
                $a->updated_at = now();
            }
            return $a;
        });

        if ($newState) {
            // If account was activated, automatically focus it
            $this->setFocusedAccount($accountId);
        } elseif (!$newState && $this->focusedAccountId === $accountId) {
            // If deactivating the focused account, focus the next active one
            $next = $this->accounts->firstWhere('is_active', true);
            if ($next) {
                $this->setFocusedAccount($next->id);
            } else {
                // No active accounts left, clear focus (should never happen now)
                $this->focusedAccountId = null;
                $this->focusedIndex = null;
                auth()->user()->profile->update(['focused_account_id' => null]);
            }
        }

        // Dispatch account status updated event for UI
        $this->dispatch('account-status-updated', id: $accountId, is_active: $newState);

        $this->dispatch('showToast', message: $newState ? 'Account activated.' : 'Account deactivated.', type: 'success');
    }

    // =============================
    // Set the focused account for calculations
    // =============================
    public function setFocusedAccount($accountId)
    {
        if (!$this->accounts->contains('id', $accountId)) {
            $this->addError('account', 'Account not found.');
            return;
        }

        $this->focusedAccountId = $accountId;
        $this->focusedAccountCache = null;

        $index = $this->accounts->values()->search(fn($a) => $a->id === $accountId);
        $this->focusedIndex = $index !== false ? $index : null;


        // Persist the focused account in the profile
        auth()->user()->profile->update(['focused_account_id' => $accountId]);

        $this->updateFocusedAccountProperties();

        $this->dispatch('account-changed', index: $this->focusedIndex);

        $this->dispatch('showToast', message: 'Focused account switched.', type: 'success');
    }

    // =============================
    // Unread alerts
    // =============================
    private function updateUnreadAlerts()
    {
        $this->unreadAlerts = auth()->user()
            ->unreadNotifications
            ->count();
    }

    // =============================
    // Add a new account
    // =============================
    public function addAccount()
    {
        if (!$this->bank_account_type) {
            $this->dispatch('validation-error');
            $this->addError('bank_account_type', 'Please select an account type.');
            return;
        }

        $exists = Account::where('profile_id', $this->profileId)
            ->where('bank_account_type', $this->bank_account_type)
            ->exists();

        if ($exists) {
            $this->addError('bank_account_type', 'You already have an account of this type.');
            return;
        }

        $account = Account::create([
            'profile_id' => $this->profileId,
            'bank_account_type' => $this->bank_account_type,
            'balance' => 0,
            'reserve_balance' => 0,
        ]);

        $this->accounts->push($account);
        $this->existingAccountTypes = $this->accounts->pluck('bank_account_type')->toArray();
        $this->reset('bank_account_type');

        $this->dispatch('account-added');
        $this->dispatch('showToast', message: 'New account added successfully.', type: 'success');
    }
};
