<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Invoice;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class InvoiceController extends Controller
{
    // Helper: sum revenue from receivable invoices (same as company analytics)
    private function sumRevenue(int $companyId, Carbon $from, Carbon $to): float
    {
        try {
            $sum = DB::table('invoices')
                ->where('company_id', $companyId)
                ->where('type', 'receivable')
                ->whereBetween('invoice_date', [$from, $to])
                ->whereIn('status', ['sent', 'viewed', 'partial', 'paid'])
                ->sum('total_amount');
            return (float) ($sum ?? 0);
        } catch (\Exception $e) {
            return 0.0;
        }
    }

    // Helper: sum expenses (same as company analytics)
    private function sumExpenses(int $companyId, Carbon $from, Carbon $to): float
    {
        $baseExpenses = (float) DB::table('expenses')
            ->where('company_id', $companyId)
            ->whereBetween('expense_date', [$from, $to])
            ->whereNotIn('status', ['rejected', 'cancelled'])
            ->sum('amount');

        $payableInvoices = (float) DB::table('invoices')
            ->where('company_id', $companyId)
            ->where('type', 'payable')
            ->whereBetween('invoice_date', [$from, $to])
            ->whereIn('status', ['sent', 'viewed', 'partial', 'paid'])
            ->sum('total_amount');

        $loanDeductions = (float) DB::table('staff_loan_deductions')
            ->join('staff_loans', 'staff_loan_deductions.staff_loan_id', '=', 'staff_loans.id')
            ->where('staff_loans.company_id', $companyId)
            ->whereBetween('staff_loan_deductions.due_date', [$from, $to])
            ->where('staff_loan_deductions.status', 'deducted')
            ->sum('staff_loan_deductions.deduction_amount');

        return $baseExpenses + $payableInvoices + $loanDeductions;
    }

    public function index(Request $request)
    {
        $user = $request->user();
        \Log::info('Invoice index called', ['user_id' => $user->id ?? null, 'is_super' => $user?->isSuperAdmin() ?? false, 'query' => $request->all()]);
        if ($user->isSuperAdmin()) {
            // Super Admin: if company_id is provided, filter by it; otherwise return all invoices across companies
            $companyId = $request->query('company_id');
            $createdBy = $request->query('created_by');
            if ($companyId) {
                $query = Invoice::where('company_id', $companyId)->with('items')->with('company');
            } else {
                $query = Invoice::with('items')->with('company');
            }
            // Allow quick filter for invoices created by the current super admin
            if ($createdBy === 'me') {
                $query->where('created_by', $user->id);
            }
        } else {
            $companyId = $user->company_id;
            $query = Invoice::where('company_id', $companyId)->with('items')->with('company');
        }

        // Filter by profit allocation payment if requested
        if ($request->has('is_profit_allocation_payment')) {
            $query->where('is_profit_allocation_payment', $request->boolean('is_profit_allocation_payment'));
        }

        $invoices = $query->latest()
            ->get()
            ->map(fn($inv) => array_merge($inv->toArray(), [
                'client'     => $inv->client_name,
                'amount'     => (float) $inv->total_amount,
                'issue_date' => $inv->invoice_date,
            ]));

        \Log::info('Invoice index result', ['user_id' => $user->id ?? null, 'count' => $invoices->count()]);

        return response()->json(['data' => $invoices]);
    }

    // Dedicated endpoint for profit allocation invoices
    public function profitAllocationInvoices(Request $request)
    {
        $user = $request->user();
        if ($user->isSuperAdmin()) {
            $companyId = $request->query('company_id');
            if ($companyId) {
                $invoices = Invoice::where('company_id', $companyId)
                    ->where('is_profit_allocation_payment', true)
                    ->with('items')
                    ->with('company')
                    ->latest()
                    ->get();
            } else {
                // All companies profit allocation invoices
                $invoices = Invoice::where('is_profit_allocation_payment', true)
                    ->with('items')
                    ->with('company')
                    ->latest()
                    ->get();
            }
        } else {
            $companyId = $user->company_id;
            $invoices = Invoice::where('company_id', $companyId)
                ->where('is_profit_allocation_payment', true)
                ->with('items')
                ->with('company')
                ->latest()
                ->get();
        }
        $invoices = $invoices->map(fn($inv) => array_merge($inv->toArray(), [
            'client'     => $inv->client_name,
            'amount'     => (float) $inv->total_amount,
            'issue_date' => $inv->invoice_date,
            'sweep_percentage' => (float) ($inv->sweep_percentage ?? 0),
        ]));

        // Log for debugging
        \Log::info('Profit allocation invoices fetched', [
            'company_id' => $companyId,
            'count' => $invoices->count(),
            'invoices' => $invoices->pluck('id', 'status')->toArray()
        ]);

        return response()->json(['data' => $invoices, 'count' => $invoices->count()]);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        // Determine target company for the invoice.
        // For normal users, use their company. For Super Admin, default to the holding company
        // (is_holding_company = true) if no company_id is provided.
        if ($user->isSuperAdmin()) {
            $companyId = $request->input('company_id');
            if (!$companyId) {
                $holding = \App\Models\Company::where('is_holding_company', true)->first();
                if ($holding) {
                    $companyId = $holding->id;
                } else {
                    // Auto-create a holding company so Super Admin can record invoices against it
                    try {
                        $holding = \App\Models\Company::create([
                            'name' => config('app.name') . ' Holding',
                            'email' => null,
                            'status' => 'active',
                            'is_holding_company' => true,
                        ]);
                        $companyId = $holding->id;
                    } catch (\Exception $e) {
                        return response()->json(['message' => 'Failed to create holding company: ' . $e->getMessage()], 500);
                    }
                }
            }
        } else {
            $companyId = $user->company_id;
        }

        $isProfitAllocation = $request->is_profit_allocation_payment ?? false;
        $isLoanRequest = $request->is_loan_request ?? false;
        $isLoanRepayment = $request->is_loan_repayment ?? false;
        $paymentMethod = $request->payment_method ?? 'bank';

        // Bank account is required for profit allocation when payment method is bank or mixed
        $bankAccountValidation = 'nullable|integer|exists:bank_accounts,id';
        if ($isProfitAllocation && ($paymentMethod === 'bank' || $paymentMethod === 'mixed')) {
            $bankAccountValidation = 'required|integer|exists:bank_accounts,id';
        }
        // When creating a loan request via invoice and payment method is bank,
        // require the borrower to pick the bank account that will receive disbursement.
        if ($isLoanRequest && $paymentMethod === 'bank') {
            $bankAccountValidation = 'required|integer|exists:bank_accounts,id';
        }

        $request->validate([
            'type'            => 'required|in:receivable,payable',
            'client_name'     => $isProfitAllocation || $isLoanRequest || $isLoanRepayment ? 'nullable|string|max:255' : 'required|string|max:255',
            'client_email'    => 'nullable|email|max:255',
            'client_address'  => 'nullable|string',
            'invoice_date'    => 'required|date',
            'due_date'        => 'required|date|after_or_equal:invoice_date',
            'bank_account_id' => $bankAccountValidation,
            'payment_method'  => 'required|in:bank,cash,mixed',
            'cash_amount'     => 'nullable|numeric|min:0',
            'notes'           => 'nullable|string',
            'terms'           => 'nullable|string',
            'tax_rate'        => 'nullable|numeric|min:0|max:100',
            'discount'        => 'nullable|numeric|min:0',
            'items'           => 'required|array|min:1',
            'items.*.description' => 'required|string|max:255',
            'items.*.quantity'    => 'required|integer|min:1',
            'items.*.unit_price'  => 'required|numeric|min:0',
            'is_profit_allocation_payment' => 'nullable|boolean',
            'allocation_month' => 'nullable|string|regex:/^\d{4}-\d{2}$/',
            'is_loan_request' => 'nullable|boolean',
            'is_loan_repayment' => 'nullable|boolean',
            'loan_id' => 'nullable|integer|exists:intercompany_loans,id',
            'loan_amount' => 'nullable|numeric|min:0|required_if:is_loan_request,true',
            'loan_interest_rate' => 'nullable|numeric|min:0|max:100|required_if:is_loan_request,true',
            'loan_term_months' => 'nullable|integer|min:1|max:360|required_if:is_loan_request,true',
            'loan_purpose' => 'nullable|string|max:1000|required_if:is_loan_request,true',
            'loan_repayment_schedule' => 'nullable|in:monthly,quarterly,annually|required_if:is_loan_request,true',
            'super_admin_bank_account_id' => 'nullable|integer|exists:super_admin_bank_accounts,id',
        ]);

        // Validate bank account belongs to company
        if ($request->bank_account_id) {
            $bankAccount = \App\Models\BankAccount::where('id', $request->bank_account_id)
                ->where('company_id', $companyId)
                ->first();
            if (!$bankAccount) {
                return response()->json(['message' => 'Invalid bank account'], 422);
            }
        }
        // Validate bank account belongs to company (unless Super Admin)
        $bankAccount = null;
        if ($request->bank_account_id) {
            if ($user->isSuperAdmin()) {
                $bankAccount = \App\Models\BankAccount::find($request->bank_account_id);
            } else {
                $bankAccount = \App\Models\BankAccount::where('id', $request->bank_account_id)
                    ->where('company_id', $companyId)
                    ->first();
            }

            if (!$bankAccount) {
                return response()->json(['message' => 'Invalid bank account'], 422);
            }
        }

        // Validate super admin holding account when provided
        $superAdminBankAccount = null;
        if ($request->super_admin_bank_account_id) {
            $superAdminBankAccount = \App\Models\SuperAdminBankAccount::find($request->super_admin_bank_account_id);
            if (!$superAdminBankAccount) {
                return response()->json(['message' => 'Invalid holding (super admin) bank account'], 422);
            }
        }

        $subtotal  = collect($request->items)->sum(fn($i) => $i['quantity'] * $i['unit_price']);
        $taxAmt    = round($subtotal * (($request->tax_rate ?? 0) / 100), 2);
        $discount  = (float) ($request->discount ?? 0);
        $total     = $subtotal + $taxAmt - $discount;

        // For payable invoices, validate sufficient balance before payment
        if ($request->type === 'payable' && $request->status === 'paid') {
            $company = \App\Models\Company::find($companyId);
            
            if ($request->payment_method === 'cash') {
                if ($company->cash_balance < $total) {
                    return response()->json([
                        'message' => 'Insufficient cash balance',
                        'required' => $total,
                        'available' => $company->cash_balance,
                        'shortfall' => $total - $company->cash_balance
                    ], 422);
                }
            } elseif ($request->payment_method === 'bank') {
                if (!$request->bank_account_id) {
                    return response()->json(['message' => 'Bank account required for bank payment'], 422);
                }
                if ($bankAccount->current_balance < $total) {
                    return response()->json([
                        'message' => 'Insufficient bank account balance',
                        'required' => $total,
                        'available' => $bankAccount->current_balance,
                        'shortfall' => $total - $bankAccount->current_balance,
                        'bank_account' => $bankAccount->bank_name . ' - ' . $bankAccount->account_number
                    ], 422);
                }
            } elseif ($request->payment_method === 'mixed') {
                $cashAmount = $request->cash_amount ?? 0;
                $bankAmount = $total - $cashAmount;
                
                if ($company->cash_balance < $cashAmount) {
                    return response()->json([
                        'message' => 'Insufficient cash balance for mixed payment',
                        'required' => $cashAmount,
                        'available' => $company->cash_balance,
                        'shortfall' => $cashAmount - $company->cash_balance
                    ], 422);
                }
                
                if (!$request->bank_account_id) {
                    return response()->json(['message' => 'Bank account required for mixed payment'], 422);
                }
                
                if ($bankAccount->current_balance < $bankAmount) {
                    return response()->json([
                        'message' => 'Insufficient bank account balance for mixed payment',
                        'required' => $bankAmount,
                        'available' => $bankAccount->current_balance,
                        'shortfall' => $bankAmount - $bankAccount->current_balance,
                        'bank_account' => $bankAccount->bank_name . ' - ' . $bankAccount->account_number
                    ], 422);
                }
            }
        }

        $num = 'INV-' . date('Y') . '-' . str_pad(
            Invoice::whereYear('created_at', date('Y'))->count() + 1,
            4, '0', STR_PAD_LEFT
        );

        // Calculate and store monthly financial data for profit allocation
        $monthRevenue = null;
        $monthExpenses = null;
        $monthNetProfit = null;
        $sweepPercentage = null;
        
        if ($request->is_profit_allocation_payment && $request->allocation_month) {
            $month = Carbon::createFromFormat('Y-m', $request->allocation_month);
            $monthStart = $month->copy()->startOfMonth();
            $monthEnd = $month->copy()->endOfMonth();
            
            $monthRevenue = $this->sumRevenue($companyId, $monthStart, $monthEnd);
            $monthExpenses = $this->sumExpenses($companyId, $monthStart, $monthEnd);
            $monthNetProfit = $monthRevenue - $monthExpenses;
            
            // Get the sweep percentage from the active rule
            $rule = \App\Models\ProfitSweepRule::where('subsidiary_id', $companyId)
                ->where('is_active', true)
                ->first();
            if ($rule) {
                $sweepPercentage = $rule->sweep_percentage;
            }
        }

        $invoice = Invoice::create([
            'invoice_number'  => $num,
            'company_id'      => $companyId,
            'bank_account_id' => $request->bank_account_id,
            'type'            => $request->type,
            'client_name'     => $request->client_name,
            'client_email'    => $request->client_email,
            'client_address'  => $request->client_address,
            'invoice_date'    => $request->invoice_date,
            'due_date'        => $request->due_date,
            'subtotal'        => $subtotal,
            'tax_amount'      => $taxAmt,
            'discount_amount' => $discount,
            'total_amount'    => $total,
            'paid_amount'     => 0,
            'balance'         => $total,
            'status'          => 'draft',
            'notes'           => $request->notes,
            'terms'           => $request->terms,
            'payment_method'  => $request->payment_method,
            'cash_amount'     => $request->cash_amount ?? 0,
            'is_profit_allocation_payment' => $request->is_profit_allocation_payment ?? false,
            'allocation_month' => $request->allocation_month,
            'month_revenue'   => $monthRevenue,
            'month_expenses'  => $monthExpenses,
            'month_net_profit'=> $monthNetProfit,
            'sweep_percentage'=> $sweepPercentage,
            'is_loan_request' => $request->is_loan_request ?? false,
            'is_loan_repayment' => $request->is_loan_repayment ?? false,
            'loan_id' => $request->loan_id,
            'super_admin_bank_account_id' => $request->super_admin_bank_account_id ?? null,
            'created_by' => $user->id,
        ]);

        // Update balances based on payment method when invoice is created with paid status
        if ($request->status === 'paid') {
            $company = \App\Models\Company::find($companyId);

            if ($invoice->type === 'receivable') {
                // Money coming in
                if ($invoice->payment_method === 'cash' || $invoice->payment_method === 'mixed') {
                    $cashAmount = $invoice->payment_method === 'cash' ? $invoice->total_amount : $invoice->cash_amount;
                    $company->increment('cash_balance', $cashAmount);
                }

                if ($invoice->payment_method === 'bank' || $invoice->payment_method === 'mixed') {
                    $bankAmount = $invoice->payment_method === 'mixed'
                        ? ($invoice->total_amount - $invoice->cash_amount)
                        : $invoice->total_amount;

                    // If invoice targets a Super Admin holding account, credit that instead
                    if ($invoice->super_admin_bank_account_id) {
                        $sa = \App\Models\SuperAdminBankAccount::find($invoice->super_admin_bank_account_id);
                        if ($sa) $sa->credit($bankAmount);
                    } elseif ($invoice->bankAccount) {
                        $invoice->bankAccount->credit($bankAmount);
                    }
                }
            } elseif ($invoice->type === 'payable') {
                // Money going out
                if ($invoice->payment_method === 'cash' || $invoice->payment_method === 'mixed') {
                    $cashAmount = $invoice->payment_method === 'cash' ? $invoice->total_amount : $invoice->cash_amount;
                    $company->decrement('cash_balance', $cashAmount);
                }

                if ($invoice->payment_method === 'bank' || $invoice->payment_method === 'mixed') {
                    $bankAmount = $invoice->payment_method === 'mixed'
                        ? ($invoice->total_amount - $invoice->cash_amount)
                        : $invoice->total_amount;
                    // 1. Debit from company bank account (money leaving company)
                    if ($invoice->bankAccount) {
                        $invoice->bankAccount->debit($bankAmount);
                    }
                    // 2. Credit to holding account (money received by holding company)
                    if ($invoice->super_admin_bank_account_id) {
                        $sa = \App\Models\SuperAdminBankAccount::find($invoice->super_admin_bank_account_id);
                        if ($sa) $sa->credit($bankAmount);
                    }
                }
            }
        }

        foreach ($request->items as $item) {
            $invoice->items()->create([
                'description' => $item['description'],
                'quantity'    => $item['quantity'],
                'unit_price'  => $item['unit_price'],
                'total_price' => $item['quantity'] * $item['unit_price'],
            ]);
        }

        // Handle profit allocation payment
        if ($invoice->is_profit_allocation_payment && $invoice->allocation_month) {
            $this->handleProfitAllocationPayment($invoice);
        }

        // Handle loan request
        if ($invoice->is_loan_request) {
            $this->handleLoanRequest($invoice, $request);
        }

        return response()->json(['data' => $invoice->load('items', 'bankAccount'), 'message' => 'Invoice created'], 201);
    }

    private function handleProfitAllocationPayment($invoice)
    {
        $company = \App\Models\Company::find($invoice->company_id);
        
                
        // Find the profit sweep rule for this company
        $rule = \App\Models\ProfitSweepRule::where('subsidiary_id', $company->id)
            ->where('is_active', true)
            ->first();
        
        if (!$rule) {
            return;
        }

        // Check if sweep already exists for this month
        $existingSweep = \App\Models\ProfitSweepTransaction::where('sweep_rule_id', $rule->id)
            ->where('year_month', $invoice->allocation_month)
            ->first();

        if ($existingSweep) {
            // Link invoice to existing sweep
            $existingSweep->update([
                'status' => 'processed',
                'actual_amount' => $invoice->total_amount,
                'processed_at' => now(),
                'processed_by' => auth()->id(),
            ]);
        } else {
            // Calculate monthly financial data using the same method as company analytics
            $month = Carbon::createFromFormat('Y-m', $invoice->allocation_month);
            $monthStart = $month->copy()->startOfMonth();
            $monthEnd = $month->copy()->endOfMonth();
            
            $revenue = $this->sumRevenue($company->id, $monthStart, $monthEnd);
            $expenses = $this->sumExpenses($company->id, $monthStart, $monthEnd);
            $netProfit = $revenue - $expenses;
            
            // Create new sweep transaction
            $sweep = \App\Models\ProfitSweepTransaction::create([
                'sweep_rule_id'     => $rule->id,
                'from_company_id'   => $company->id,
                'to_company_id'     => null, // Super Admin is recipient
                'sweep_date'        => now(),
                'year_month'        => $invoice->allocation_month,
                'calculated_amount' => $invoice->total_amount,
                'actual_amount'     => $invoice->total_amount,
                'subsidiary_profit' => $netProfit,
                'month_revenue'     => $revenue,
                'month_expenses'    => $expenses,
                'month_net_profit'  => $netProfit,
                'is_no_profit_month'=> $netProfit <= 0,
                'status'            => 'processed',
                'notes'             => 'Paid via invoice ' . $invoice->invoice_number,
                'processed_by'      => auth()->id(),
                'processed_at'     => now(),
                'is_super_admin_recipient' => true,
            ]);
        }

        // Deduct from company net profit
        $company->decrement('net_profit', $invoice->total_amount);

        // Credit Super Admin bank account if payment method is bank or mixed
        if ($invoice->payment_method === 'bank' || $invoice->payment_method === 'mixed') {
            $bankAmount = $invoice->payment_method === 'mixed' 
                ? ($invoice->total_amount - $invoice->cash_amount) 
                : $invoice->total_amount;
            
            // If the invoice has a bank account, credit the company's bank account
            // Otherwise, we need to credit the Super Admin's bank account
            // For now, we'll update Super Admin financials
        }

        // Update Super Admin financials to include this profit sweep as revenue
        try {
            $sweepMonth = Carbon::parse($invoice->invoice_date)->format('Y-m');
            \App\Models\SuperAdminFinancial::recalculateMonth($sweepMonth);
        } catch (\Exception $e) {
            // Log silently; don't fail the payment
        }
    }

    private function handleLoanRequest($invoice, $request = null)
    {
        $company = \App\Models\Company::find($invoice->company_id);
        
        if (!$company) {
            return;
        }

        // Extract loan details from form data or invoice
        $loanAmount = $request->loan_amount ?? $invoice->total_amount ?? 0;
        $interestRate = $request->loan_interest_rate ?? 0;
        $termMonths = $request->loan_term_months ?? 12;
        $purpose = $request->loan_purpose ?? $invoice->notes ?? 'Loan request via invoice';
        $repaymentSchedule = $request->loan_repayment_schedule ?? 'monthly';
        $paymentMethod = $invoice->payment_method ?? 'bank';
        $bankAccountId = $invoice->bank_account_id;

        // Calculate total interest as a flat percentage of principal for the loan term
        // (business rule: `loan_interest_rate` represents the percentage applied to the principal)
        $totalInterest = round($loanAmount * ($interestRate / 100), 2);
        $totalRepayable = round($loanAmount + $totalInterest, 2);

        // Update invoice total to include interest
        // For the invoice that initiated the loan request, keep the invoice representing the principal amount.
        // The loan record (IntercompanyLoan) will contain the outstanding balance including interest.
        if ($invoice->items()->count() > 0) {
            $invoice->items()->first()->update([
                'unit_price' => $loanAmount,
                'description' => "Loan Request - Principal: ₦{$loanAmount} (Interest on loan: ₦{$totalInterest} applied to loan record)",
            ]);
            // Update invoice totals to reflect principal only
            $invoice->update([
                'subtotal' => $loanAmount,
                'tax_amount' => 0,
                'discount_amount' => 0,
                'total_amount' => $loanAmount,
                'balance' => $loanAmount,
            ]);
        }

        $loan = \App\Models\IntercompanyLoan::create([
            'loan_number'         => 'LN-' . date('Y') . '-' . strtoupper(substr(uniqid(), -6)),
            'lender_company_id'   => null, // Super Admin is lender
            'borrower_company_id' => $company->id,
            'principal_amount'    => $loanAmount,
            'outstanding_balance' => $totalRepayable,
            'interest_rate'       => $interestRate,
            'interest_type'       => 'simple',
            'disbursement_date'   => null, // Will be set on approval
            'maturity_date'       => now()->addMonths($termMonths)->toDateString(),
            'due_date'            => now()->addMonths($termMonths)->toDateString(),
            'term_months'         => $termMonths,
            'purpose'             => $purpose,
            'payment_frequency'   => $repaymentSchedule,
            'status'              => 'pending', // Pending approval
            'terms_conditions'    => 'Standard inter-company loan terms',
            'requested_by'        => auth()->id(),
            'payment_method'      => $paymentMethod,
            'bank_account_id'     => $bankAccountId,
            'is_super_admin_lender' => true,
        ]);

        // Link invoice to loan
        $invoice->update(['loan_id' => $loan->id]);
    }

    public function show(Request $request, $id)
    {
        $user    = $request->user();
        $invoice = Invoice::with(['items', 'payments'])->findOrFail($id);

        if (!$user->isSuperAdmin() && $invoice->company_id !== $user->company_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        return response()->json(['data' => $invoice]);
    }

    public function markPaid(Request $request, $id)
    {
        $user    = $request->user();
        $invoice = Invoice::findOrFail($id);

        // Company users may only act on invoices for their own company
        if (!$user->isSuperAdmin() && $invoice->company_id !== $user->company_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Super Admins may only perform state-changing actions on invoices they created
        if ($user->isSuperAdmin() && $invoice->created_by !== $user->id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Check if already paid to prevent double updates
        if ($invoice->status === 'paid') {
            return response()->json(['message' => 'Invoice is already paid'], 400);
        }

        // For payable invoices, validate sufficient balance before payment
        if ($invoice->type === 'payable') {
            $company = \App\Models\Company::find($invoice->company_id);
            $total = $invoice->total_amount;
            
            if ($invoice->payment_method === 'cash') {
                if ($company->cash_balance < $total) {
                    return response()->json([
                        'message' => 'Insufficient cash balance',
                        'required' => $total,
                        'available' => $company->cash_balance,
                        'shortfall' => $total - $company->cash_balance
                    ], 422);
                }
            } elseif ($invoice->payment_method === 'bank') {
                if (!$invoice->bankAccount) {
                    return response()->json(['message' => 'Bank account required for bank payment'], 422);
                }
                if ($invoice->bankAccount->current_balance < $total) {
                    return response()->json([
                        'message' => 'Insufficient bank account balance',
                        'required' => $total,
                        'available' => $invoice->bankAccount->current_balance,
                        'shortfall' => $total - $invoice->bankAccount->current_balance,
                        'bank_account' => $invoice->bankAccount->bank_name . ' - ' . $invoice->bankAccount->account_number
                    ], 422);
                }
            } elseif ($invoice->payment_method === 'mixed') {
                $cashAmount = $invoice->cash_amount ?? 0;
                $bankAmount = $total - $cashAmount;
                
                if ($company->cash_balance < $cashAmount) {
                    return response()->json([
                        'message' => 'Insufficient cash balance for mixed payment',
                        'required' => $cashAmount,
                        'available' => $company->cash_balance,
                        'shortfall' => $cashAmount - $company->cash_balance
                    ], 422);
                }
                
                if (!$invoice->bankAccount) {
                    return response()->json(['message' => 'Bank account required for mixed payment'], 422);
                }
                
                if ($invoice->bankAccount->current_balance < $bankAmount) {
                    return response()->json([
                        'message' => 'Insufficient bank account balance for mixed payment',
                        'required' => $bankAmount,
                        'available' => $invoice->bankAccount->current_balance,
                        'shortfall' => $bankAmount - $invoice->bankAccount->current_balance,
                        'bank_account' => $invoice->bankAccount->bank_name . ' - ' . $invoice->bankAccount->account_number
                    ], 422);
                }
            }
        }

        $oldStatus = $invoice->status;
        $invoice->update([
            'status'     => 'paid',
            'paid_amount'=> $invoice->total_amount,
            'balance'    => 0,
        ]);

        // Update balances based on payment method when marking as paid (only if not already paid)
        $company = \App\Models\Company::find($invoice->company_id);
        
        if ($invoice->type === 'receivable') {
            // Money coming in
            if ($invoice->payment_method === 'cash' || $invoice->payment_method === 'mixed') {
                $cashAmount = $invoice->payment_method === 'cash' ? $invoice->total_amount : $invoice->cash_amount;
                $company->increment('cash_balance', $cashAmount);
            }
            if ($invoice->payment_method === 'bank' || $invoice->payment_method === 'mixed') {
                $bankAmount = $invoice->payment_method === 'mixed' 
                    ? ($invoice->total_amount - $invoice->cash_amount) 
                    : $invoice->total_amount;
                // If invoice points to a Super Admin holding account, credit that instead
                if ($invoice->super_admin_bank_account_id) {
                    $sa = \App\Models\SuperAdminBankAccount::find($invoice->super_admin_bank_account_id);
                    if ($sa) $sa->credit($bankAmount);
                } elseif ($invoice->bankAccount) {
                    $invoice->bankAccount->credit($bankAmount);
                }
            }
        } elseif ($invoice->type === 'payable') {
            // Money going out from company to holding/super-admin
            if ($invoice->payment_method === 'cash' || $invoice->payment_method === 'mixed') {
                $cashAmount = $invoice->payment_method === 'cash' ? $invoice->total_amount : $invoice->cash_amount;
                $company->decrement('cash_balance', $cashAmount);
            }
            if ($invoice->payment_method === 'bank' || $invoice->payment_method === 'mixed') {
                $bankAmount = $invoice->payment_method === 'mixed' 
                    ? ($invoice->total_amount - $invoice->cash_amount) 
                    : $invoice->total_amount;
                
                // 1. Debit from company bank account (money leaving company)
                if ($invoice->bankAccount) {
                    $invoice->bankAccount->debit($bankAmount);
                }
                
                // 2. Credit to holding account (money received by holding company)
                if ($invoice->super_admin_bank_account_id) {
                    $sa = \App\Models\SuperAdminBankAccount::find($invoice->super_admin_bank_account_id);
                    if ($sa) $sa->credit($bankAmount);
                }
            }
        }

        // Handle profit allocation payment when marked as paid
        if ($invoice->is_profit_allocation_payment && $invoice->allocation_month && $oldStatus !== 'paid') {
            $this->handleProfitAllocationPayment($invoice);
        }

        // Handle loan request when marked as paid
        if ($invoice->is_loan_request && $oldStatus !== 'paid') {
            $this->handleLoanRequest($invoice, $request);
        }

        return response()->json(['data' => $invoice, 'message' => 'Invoice marked as paid']);
    }

    public function updateStatus(Request $request, $id)
    {
        $user    = $request->user();
        $invoice = Invoice::findOrFail($id);

        // Company users may only act on invoices for their own company
        if (!$user->isSuperAdmin() && $invoice->company_id !== $user->company_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Super Admins may only perform state-changing actions on invoices they created
        if ($user->isSuperAdmin() && $invoice->created_by !== $user->id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // If client requests to set status to paid, route through markPaid to handle balances
        if ($request->status === 'paid') {
            return $this->markPaid($request, $id);
        }

        $request->validate(['status' => 'required|in:draft,sent,viewed,partial,paid,overdue,cancelled']);
        $invoice->update(['status' => $request->status]);

        return response()->json(['data' => $invoice, 'message' => 'Status updated']);
    }
}
