<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ProfitSweepTransaction;
use App\Models\ProfitSweepRule;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class ProfitSweepController 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 sweeps(Request $request)
    {
        $user = $request->user();
        $query = ProfitSweepTransaction::with(['fromCompany', 'toCompany', 'sweepRule', 'superAdminBankAccount']);

        if (!$user->isSuperAdmin()) {
            $query->where('from_company_id', $user->company_id);
        }

        // Filter by date range if provided
        if ($request->filled('from_date') && $request->filled('to_date')) {
            $query->whereBetween('sweep_date', [$request->from_date, $request->to_date]);
        }

        // Filter by year_month if provided
        if ($request->filled('year_month')) {
            $query->where('year_month', $request->year_month);
        }

        $sweeps = $query->latest()->get()->map(function ($s) {
            // Use the stored financial data from the transaction itself
            $revenue = (float) ($s->month_revenue ?? 0);
            $expenses = (float) ($s->month_expenses ?? 0);
            $netProfit = (float) ($s->month_net_profit ?? 0);
            
            return [
                'id' => $s->id,
                'year_month' => $s->year_month,
                'source_company' => $s->fromCompany,
                'target_company' => $s->is_super_admin_recipient ? null : $s->toCompany,
                'is_super_admin_recipient' => $s->is_super_admin_recipient,
                'rule' => $s->sweepRule,
                'amount' => $s->actual_amount ?? $s->calculated_amount,
                'sweep_percentage' => $s->sweepRule?->sweep_percentage ?? 0,
                'sweep_date' => $s->sweep_date,
                'month_revenue' => $revenue,
                'month_expenses' => $expenses,
                'month_net_profit' => $netProfit,
                'is_no_profit_month' => $netProfit <= 0,
                'status' => $s->status,
                'notes' => $s->notes,
            ];
        });

        // Calculate totals for all-time view
        $totals = [
            'total_revenue' => $sweeps->sum('month_revenue'),
            'total_expenses' => $sweeps->sum('month_expenses'),
            'total_net_profit' => $sweeps->sum('month_net_profit'),
            'total_swept' => $sweeps->sum('amount'),
        ];

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

    // Get available months for profit allocation
    public function availableMonths(Request $request)
    {
        $user = $request->user();
        
        // If company_id is provided (for Super Admin viewing subsidiary data), use it
        // Otherwise use the user's company_id
        $companyId = $request->query('company_id') 
            ? (int) $request->query('company_id') 
            : $user->company_id;

        $company = Company::find($companyId);
        if (!$company) {
            return response()->json(['data' => []]);
        }

        // Calculate per month using the same method as company analytics
        $months = [];
        for ($i = 12; $i >= 0; $i--) {
            $month = Carbon::now()->subMonths($i);
            $ym = $month->format('Y-m');
            $monthStart = $month->copy()->startOfMonth();
            $monthEnd = $month->copy()->endOfMonth();
            
            // Calculate revenue and expenses for this month (same as company analytics)
            $revenue = $this->sumRevenue($companyId, $monthStart, $monthEnd);
            $expenses = $this->sumExpenses($companyId, $monthStart, $monthEnd);
            $netProfit = $revenue - $expenses;
            $availableProfit = $netProfit;
            
            // Check if sweep already exists for this month
            $existingSweep = ProfitSweepTransaction::where('from_company_id', $companyId)
                ->where('year_month', $ym)
                ->first();

            $months[] = [
                'year_month' => $ym,
                'month_name' => $month->format('F Y'),
                'revenue' => $revenue,
                'expenses' => $expenses,
                'net_profit' => $netProfit,
                'available_profit' => $availableProfit,
                'has_sweep' => $existingSweep !== null,
                'sweep_amount' => $existingSweep ? (float) $existingSweep->actual_amount : 0,
                'is_no_profit_month' => $netProfit <= 0,
            ];
        }

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

    public function rules(Request $request)
    {
        $user = $request->user();
        $query = ProfitSweepRule::with(['subsidiary', 'parentCompany']);

        if (!$user->hasRole('Super Admin')) {
            $query->where('subsidiary_id', $user->company_id);
        }

        $rules = $query->latest()->get()->map(function ($r) {
            return [
                'id' => $r->id,
                'rule_name' => ucfirst($r->sweep_type) . ' sweep — ' . $r->subsidiary?->name,
                'source_company' => $r->subsidiary,
                'sweep_percentage' => $r->sweep_percentage,
                'frequency' => $r->frequency,
                'minimum_amount' => $r->threshold_amount,
                'is_active' => $r->is_active,
                'last_executed_at' => $r->transactions()->latest()->first()?->processed_at,
            ];
        });

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

    public function store(Request $request)
    {
        $user = $request->user();

        $validated = $request->validate([
            'rule_id'       => 'required|exists:profit_sweep_rules,id',
            'year_month'    => 'required|string|regex:/^\d{4}-\d{2}$/', // Format: '2024-04'
            'to_company_id' => 'nullable|exists:companies,id',
            'super_admin_bank_account_id' => 'nullable|exists:super_admin_bank_accounts,id',
            'notes'         => 'nullable|string|max:1000',
        ]);

        $rule = ProfitSweepRule::with(['subsidiary', 'parentCompany'])->findOrFail($validated['rule_id']);

        // Authorize: super admin, or user belongs to the source company
        if (!$user->hasRole('Super Admin') && $user->company_id != $rule->subsidiary_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $company = $rule->subsidiary;
        $yearMonth = $validated['year_month'];

        // Check if this month already has a sweep
        $existingSweep = ProfitSweepTransaction::where('sweep_rule_id', $rule->id)
            ->where('year_month', $yearMonth)
            ->first();
        if ($existingSweep) {
            return response()->json(['message' => 'Profit sweep already exists for ' . $yearMonth], 400);
        }

        // Profit sweeps go to Super Admin
        $toCompanyId = null; // No company, Super Admin is recipient

        // ── Get the company's current financial data ──
        // Use company_id from request body if provided (for Super Admin), otherwise use rule's subsidiary
        $targetCompanyId = $request->input('company_id') 
            ? (int) $request->input('company_id') 
            : $company->id;
            
        $targetCompany = Company::find($targetCompanyId);
        
        // Use company's stored financial data (matches company table)
        $monthlyRevenue  = (float) ($targetCompany->revenue ?? 0);
        $monthlyExpenses = (float) ($targetCompany->expenses_manual ?? 0);
        $netProfit       = (float) ($targetCompany->net_profit ?? 0);
        $availableProfit = $netProfit;

        // Check if it's a no-profit month
        $isNoProfitMonth = $netProfit <= 0;

        if ($isNoProfitMonth) {
            // Create a sweep record with zero amount for no-profit months
            $sweep = ProfitSweepTransaction::create([
                'sweep_rule_id'     => $rule->id,
                'from_company_id'   => $rule->subsidiary_id,
                'to_company_id'     => $toCompanyId,
                'sweep_date'        => now(),
                'year_month'        => $yearMonth,
                'calculated_amount' => 0,
                'actual_amount'     => 0,
                'subsidiary_profit' => $netProfit,
                'month_revenue'     => $monthlyRevenue,
                'month_expenses'    => $monthlyExpenses,
                'month_net_profit'  => $netProfit,
                'is_no_profit_month'=> true,
                'status'            => 'completed',
                'notes'             => 'No profit month - Expenses (₦' . number_format($monthlyExpenses, 2) . ') exceeded Revenue (₦' . number_format($monthlyRevenue, 2) . ')',
                'processed_by'      => $user->id,
                'processed_at'     => now(),
                'is_super_admin_recipient' => true,
                'super_admin_bank_account_id' => $validated['super_admin_bank_account_id'] ?? null,
            ]);

            return response()->json([
                'data' => [
                    'id'               => $sweep->id,
                    'year_month'       => $sweep->year_month,
                    'source_company'   => $sweep->fromCompany,
                    'target_company'   => $sweep->toCompany,
                    'amount'           => 0,
                    'month_revenue'    => $monthlyRevenue,
                    'month_expenses'   => $monthlyExpenses,
                    'month_net_profit' => $netProfit,
                    'is_no_profit_month'=> true,
                    'status'           => $sweep->status,
                ],
                'message' => 'No profit for ' . $yearMonth . '. Revenue: ₦' . number_format($monthlyRevenue, 2) . ', Expenses: ₦' . number_format($monthlyExpenses, 2) . ', Net Profit: ₦' . number_format($netProfit, 2)
            ], 201);
        }

        if ($availableProfit <= 0) {
            return response()->json([
                'message' => 'Insufficient net profit for profit allocation. ' .
                    'Revenue: ₦' . number_format($monthlyRevenue, 2) .
                    ' — Expenses: ₦' . number_format($monthlyExpenses, 2) .
                    ' — Net Profit: ₦' . number_format($netProfit, 2) .
                    ' — Available: ₦' . number_format($availableProfit, 2)
            ], 422);
        }

        $calculatedAmount = round($availableProfit * ($rule->sweep_percentage / 100), 2);
        if ($calculatedAmount <= 0) {
            return response()->json([
                'message' => 'Calculated sweep amount is zero. Check net profit and rule percentage.'
            ], 422);
        }

        // Deduct from cash balance
        $company->cash_balance = max(0, ($company->cash_balance ?? 0) - $calculatedAmount);
        $company->save();

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

        // Update monthly profit_swept so available_profit reduces
        if ($mfin instanceof \Illuminate\Database\Eloquent\Model) {
            $mfin->profit_swept += $calculatedAmount;
            $mfin->available_profit = max(0, $mfin->net_profit - $mfin->profit_swept);
            $mfin->save();
        }

        $sweep = ProfitSweepTransaction::create([
            'sweep_rule_id'     => $rule->id,
            'from_company_id'   => $rule->subsidiary_id,
            'to_company_id'     => $toCompanyId,
            'sweep_date'        => now(),
            'year_month'        => $yearMonth,
            'calculated_amount' => $calculatedAmount,
            'actual_amount'     => $calculatedAmount,
            'subsidiary_profit' => $netProfit,
            'month_revenue'     => $monthlyRevenue,
            'month_expenses'    => $monthlyExpenses,
            'month_net_profit'  => $netProfit,
            'is_no_profit_month'=> false,
            'status'            => 'pending',
            'notes'             => ($validated['notes'] ?? '') . ' | ' . $yearMonth . ' | ' . $rule->sweep_percentage . '% of ₦' . number_format($netProfit, 2) . ' net profit',
            'processed_by'      => $user->id,
            'is_super_admin_recipient' => true,
            'super_admin_bank_account_id' => $validated['super_admin_bank_account_id'] ?? null,
        ]);

        // Credit the selected Super Admin bank account
        if ($validated['super_admin_bank_account_id'] ?? null) {
            $bankAccount = \App\Models\SuperAdminBankAccount::find($validated['super_admin_bank_account_id']);
            if ($bankAccount) {
                $bankAccount->credit($calculatedAmount);
            }
        }

        return response()->json([
            'data' => [
                'id'               => $sweep->id,
                'year_month'       => $sweep->year_month,
                'source_company'   => $sweep->fromCompany,
                'target_company'   => $sweep->toCompany,
                'amount'           => $sweep->actual_amount,
                'sweep_percentage' => $rule->sweep_percentage,
                'month_revenue'    => $monthlyRevenue,
                'month_expenses'   => $monthlyExpenses,
                'month_net_profit' => $netProfit,
                'is_no_profit_month'=> false,
                'status'           => $sweep->status,
            ],
            'message' => 'Profit sweep of ₦' . number_format($calculatedAmount, 2) . ' for ' . $yearMonth . ' created and deducted from company balance.'
        ], 201);
    }

    public function storeRule(Request $request)
    {
        $user = $request->user();
        
        // Only Super Admin can create sweep rules
        if (!$user->isSuperAdmin()) {
            return response()->json(['message' => 'Unauthorized. Only Super Admin can create sweep rules'], 403);
        }

        $validated = $request->validate([
            'subsidiary_id'     => 'required|exists:companies,id',
            'sweep_percentage'  => 'required|numeric|min:0.01|max:100',
            'frequency'         => 'required|in:monthly,quarterly,annual',
        ]);

        // Parent company is Super Admin (no company ID)
        $parentId = null;

        $rule = ProfitSweepRule::updateOrCreate(
            [
                'subsidiary_id'    => $validated['subsidiary_id'],
                'parent_company_id'=> $parentId,
                'frequency'        => $validated['frequency'],
            ],
            [
                'sweep_type'       => 'percentage',
                'sweep_percentage' => $validated['sweep_percentage'],
                'is_active'        => true,
                'effective_from'   => now(),
            ]
        );

        return response()->json(['data' => $rule->load(['subsidiary','parentCompany']), 'message' => 'Rule saved'], 201);
    }

    public function uploadReceipt(Request $request, $id)
    {
        $user = $request->user();
        $sweep = ProfitSweepTransaction::findOrFail($id);

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

        $request->validate(['receipt' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048']);
        $path = $request->file('receipt')->store('sweep_receipts', 'public');

        $sweep->update(['receipt_path' => $path, 'sent_at' => now(), 'sent_by' => $user->id, 'status' => 'processed']);

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