<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Partner;
use App\Models\Account;
use App\Services\AccountingService;
use Illuminate\Support\Facades\DB;

class RecalculateBalances extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'recalculate:balances {--partner= : ID of specific partner to recalculate}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Recalculate partner current_balance from Journal Entries';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $this->info('Starting balance recalculation...');

        $partnerId = $this->option('partner');
        
        $query = Partner::query();
        if ($partnerId) {
            $query->where('id', $partnerId);
        }

        $partners = $query->get();
        $bar = $this->output->createProgressBar($partners->count());

        $arAccount = Account::where('code', AccountingService::ACCOUNTS_RECEIVABLE)->first();
        $apAccount = Account::where('code', AccountingService::ACCOUNTS_PAYABLE)->first() 
            ?? Account::where('code', '2100')->first(); // Fallback to 2100 if constant missing or different

        if (!$arAccount && !$apAccount) {
            $this->error('AR and AP accounts not found. Cannot recalculate.');
            return;
        }

        foreach ($partners as $partner) {
            $balance = 0;

            // Determine if Customer or Supplier based on Type
            // But a partner can be both.
            // Best approach: Sum AR Account lines (Debit +, Credit -) AND Sum AP Account lines (Credit +, Debit -)?
            // If we assume `current_balance` is a single net number:
            // Positive = They Owe Us (Asset)
            // Negative = We Owe Them (Liability)
            
            // Calculate AR Balance (Asset)
            $arBalance = 0;
            if ($arAccount) {
                $debit = $partner->journalEntryLines()->where('account_id', $arAccount->id)->sum('debit');
                $credit = $partner->journalEntryLines()->where('account_id', $arAccount->id)->sum('credit');
                $arBalance = $debit - $credit;
            }

            // Calculate AP Balance (Liability) - tracked as Credit
            $apBalance = 0;
            if ($apAccount) {
                $debit = $partner->journalEntryLines()->where('account_id', $apAccount->id)->sum('debit');
                $credit = $partner->journalEntryLines()->where('account_id', $apAccount->id)->sum('credit');
                $apBalance = $credit - $debit; // Liability is Credit normal.
            }

            // Net Balance
            // If they owe us 100 (AR), Balance = 100.
            // If we owe them 100 (AP), Balance = -100.
            // Result = AR - AP.
            // Example: Sold 100 (AR 100). Bought 50 (AP 50). Net we are owed 50.
            // Correct.
            
            $netBalance = $arBalance - $apBalance;

            // Update Partner
            $partner->update(['current_balance' => $netBalance]);
            
            $bar->advance();
        }

        $bar->finish();
        $this->newLine();
        $this->info('Balances recalculated successfully.');
    }
}
