<?php

namespace App\Http\Controllers\Api;

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

class TreasuryController extends Controller
{
    public function index(Request $request)
    {
        $user = $request->user();

        // Scope: super admin sees all companies; company admin sees own + subsidiaries
        if ($user->isSuperAdmin()) {
            $companyIds = Company::pluck('id')->toArray();
        } else {
            $companyIds = Company::where('id', $user->company_id)
                ->orWhere('parent_company_id', $user->company_id)
                ->pluck('id')->toArray();
        }

        if (empty($companyIds)) {
            return response()->json($this->emptyResponse());
        }

        $companies = DB::table('companies')->whereIn('id', $companyIds)->get();

        // ── Group KPIs ─────────────────────────────────────────────
        $totalRevenue = $companies->sum(fn($c) => (float)($c->revenue ?? 0));
        $totalCash    = $companies->sum(fn($c) => (float)($c->cash_balance ?? 0));
        $totalLiab    = $companies->sum(fn($c) => (float)($c->total_liabilities ?? 0));

        // Assets: prefer company_assets table sum, fall back to companies.total_assets
        $assetTableSum = (float) DB::table('company_assets')
            ->whereIn('company_id', $companyIds)
            ->where('status', 'active')
            ->sum('current_value');
        $assetFieldSum = $companies->sum(fn($c) => (float)($c->total_assets ?? 0));
        $totalAssets   = $assetTableSum > 0 ? $assetTableSum : $assetFieldSum;

        // Total expenses: prefer expenses_manual, fall back to real expenses table
        $companiesWithManual = $companies->filter(fn($c) => isset($c->expenses_manual) && $c->expenses_manual !== null);
        $totalExpenses = $companiesWithManual->sum(fn($c) => (float)($c->expenses_manual ?? 0));
        if ($companiesWithManual->count() < count($companyIds)) {
            // Also add actual expenses for companies without a manual override
            $excludeIds = $companiesWithManual->pluck('id')->toArray();
            $remainIds  = array_diff($companyIds, $excludeIds);
            if (!empty($remainIds)) {
                $totalExpenses += (float) Expense::whereIn('company_id', $remainIds)
                    ->whereNotIn('status', ['rejected', 'cancelled'])
                    ->sum('amount');
            }
        }

        $netPosition = $totalAssets - $totalLiab;

        // ── 6-month cash flow trend ────────────────────────────────
        $mNames    = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
        $cashFlow  = [];
        $invGrandTotal = 0;

        for ($i = 5; $i >= 0; $i--) {
            $m    = Carbon::now()->subMonths($i);
            $mS   = $m->copy()->startOfMonth();
            $mE   = $m->copy()->endOfMonth();

            $inflow = 0;
            try {
                $inflow = (float) DB::table('invoices')
                    ->whereIn('company_id', $companyIds)
                    ->where('type', 'receivable')
                    ->whereBetween('invoice_date', [$mS, $mE])
                    ->whereIn('status', ['sent', 'viewed', 'partial', 'paid'])
                    ->sum('total_amount');
            } catch (\Exception $e) {}

            $invGrandTotal += $inflow;

            $outflow = (float) Expense::whereIn('company_id', $companyIds)
                ->whereBetween('expense_date', [$mS, $mE])
                ->whereNotIn('status', ['rejected', 'cancelled'])
                ->sum('amount');

            $cashFlow[] = [
                'month'   => $mNames[$m->month - 1],
                'inflow'  => (int) $inflow,
                'outflow' => (int) $outflow,
                'net'     => (int) ($inflow - $outflow),
            ];
        }

        // If no invoice data, spread stored annual revenue across months
        if ($invGrandTotal === 0 && $totalRevenue > 0) {
            $monthly  = (int) ($totalRevenue / 12);
            $cashFlow = array_map(fn($r) => array_merge($r, [
                'inflow' => $monthly,
                'net'    => $monthly - $r['outflow'],
            ]), $cashFlow);
        }

        // ── Capital allocation by expense category ─────────────────
        $catRows = [];
        try {
            $catRows = Expense::whereIn('expenses.company_id', $companyIds)
                ->whereNotIn('expenses.status', ['rejected', 'cancelled'])
                ->join('expense_categories', 'expenses.expense_category_id', '=', 'expense_categories.id')
                ->select('expense_categories.name as cat', DB::raw('SUM(expenses.amount) as total'))
                ->groupBy('cat')
                ->orderByDesc('total')
                ->limit(6)
                ->get()
                ->toArray();
        } catch (\Exception $e) {}

        $catTotal     = array_sum(array_column($catRows, 'total'));
        $allocation   = array_map(fn($r) => [
            'name'  => $r->cat,
            'value' => $catTotal > 0 ? round(($r->total / $catTotal) * 100, 1) : 0,
            'amount'=> (int) $r->total,
        ], $catRows);

        // ── Per-company breakdown ──────────────────────────────────
        $companyBreakdown = $companies->map(function ($c) use ($companyIds) {
            $expManual = isset($c->expenses_manual) && $c->expenses_manual !== null
                ? (float)$c->expenses_manual
                : (float) Expense::where('company_id', $c->id)->whereNotIn('status', ['rejected','cancelled'])->sum('amount');

            $assetSum = (float) DB::table('company_assets')
                ->where('company_id', $c->id)->where('status', 'active')->sum('current_value');

            return [
                'id'       => $c->id,
                'name'     => $c->name,
                'revenue'  => (float)($c->revenue ?? 0),
                'expenses' => $expManual,
                'cash'     => (float)($c->cash_balance ?? 0),
                'assets'   => $assetSum > 0 ? $assetSum : (float)($c->total_assets ?? 0),
                'status'   => $c->health_status ?? 'good',
            ];
        })->values()->toArray();

        // ── Recent transactions (loans + profit sweeps + expenses) ─
        $recentTx = [];
        try {
            $loans = DB::table('intercompany_loans')
                ->whereIn('borrower_company_id', $companyIds)
                ->orWhereIn('lender_company_id', $companyIds)
                ->orderByDesc('created_at')
                ->limit(5)
                ->get();

            foreach ($loans as $ln) {
                $lender   = DB::table('companies')->where('id', $ln->lender_company_id)->value('name');
                $borrower = DB::table('companies')->where('id', $ln->borrower_company_id)->value('name');
                $recentTx[] = [
                    'id'     => 'L'.$ln->id,
                    'desc'   => "Loan: {$lender} → {$borrower}",
                    'amount' => -(float)($ln->amount ?? 0),
                    'date'   => isset($ln->created_at) ? Carbon::parse($ln->created_at)->format('M d') : '—',
                    'type'   => 'debit',
                    'status' => $ln->status ?? 'pending',
                ];
            }
        } catch (\Exception $e) {}

        try {
            $sweeps = DB::table('profit_sweeps')
                ->whereIn('from_company_id', $companyIds)
                ->orWhereIn('to_company_id', $companyIds)
                ->orderByDesc('created_at')
                ->limit(5)
                ->get();

            foreach ($sweeps as $sw) {
                $from = DB::table('companies')->where('id', $sw->from_company_id)->value('name');
                $to   = DB::table('companies')->where('id', $sw->to_company_id)->value('name');
                $recentTx[] = [
                    'id'     => 'S'.$sw->id,
                    'desc'   => "Profit sweep: {$from} → {$to}",
                    'amount' => (float)($sw->amount ?? 0),
                    'date'   => isset($sw->created_at) ? Carbon::parse($sw->created_at)->format('M d') : '—',
                    'type'   => 'credit',
                    'status' => $sw->status ?? 'completed',
                ];
            }
        } catch (\Exception $e) {}

        // Sort recent tx by date descending
        usort($recentTx, fn($a, $b) => strcmp($b['date'], $a['date']));
        $recentTx = array_slice($recentTx, 0, 10);

        return response()->json([
            'kpis' => [
                'total_revenue'  => $totalRevenue,
                'total_expenses' => $totalExpenses,
                'total_assets'   => $totalAssets,
                'total_liab'     => $totalLiab,
                'total_cash'     => $totalCash,
                'net_position'   => $netPosition,
                'net_profit'     => (function() use ($request) {
                    $companyId = $request->user()->company_id;
                    $mfin = \App\Models\MonthlyCompanyFinancial::recalculateMonth($companyId, now()->format('Y-m'));
                    return (float) $mfin->net_profit;
                })(),
            ],
            'cash_flow'        => $cashFlow,
            'allocation'       => $allocation,
            'companies'        => $companyBreakdown,
            'recent_tx'        => $recentTx,
            'company_count'    => count($companyIds),
        ]);
    }

    private function emptyResponse(): array
    {
        return [
            'kpis'          => ['total_revenue'=>0,'total_expenses'=>0,'total_assets'=>0,'total_liab'=>0,'total_cash'=>0,'net_position'=>0,'net_profit'=>0],
            'cash_flow'     => [],
            'allocation'    => [],
            'companies'     => [],
            'recent_tx'     => [],
            'company_count' => 0,
        ];
    }
}
