import { Link, useNavigate, useParams } from "react-router-dom";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import { accounting } from "@/lib/accountingClient";
import { useCompanyId } from "./lib/useCompanyId";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { ArrowLeft, ChevronDown, ChevronRight, MoveRight, Wand2, Save, CheckCircle2 } from "lucide-react";
import { toast } from "sonner";
import { money } from "./lib/format";

const MONTHS = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];
const QUARTERS = ["Q1","Q2","Q3","Q4"];

function periodLabels(p: string) {
  if (p === "monthly") return MONTHS;
  if (p === "quarterly") return QUARTERS;
  return ["Year"];
}

type Grid = Record<string, string[]>;

export default function AccountingBudgetDetailPage({ basePath = "/dashboard/accounting/budgets" }: { basePath?: string } = {}) {
  const { id = "" } = useParams();
  const { companyId } = useCompanyId();
  const cid = companyId ?? "";
  const cur = "USD";
  const navigate = useNavigate();
  const qc = useQueryClient();

  const [grid, setGrid] = useState<Grid>({});
  const [expanded, setExpanded] = useState<Record<string, boolean>>({ income: true, expense: true });
  const [hideZero, setHideZero] = useState(false);
  const [saving, setSaving] = useState(false);
  const [tab, setTab] = useState<"summary" | "edit">("summary");
  const [summarySection, setSummarySection] = useState<"income" | "expense">("income");

  const { data: budget, isLoading: bLoading } = useQuery({
    queryKey: ["budget", id],
    enabled: !!id,
    queryFn: async () => {
      const { data, error } = await accounting.from("budgets").select("*").eq("id", id).single();
      if (error) console.error("Budget query error:", error);
      return data;
    },
  });

  const { data: accounts = [] } = useQuery({
    queryKey: ["accounts", cid],
    enabled: !!cid,
    queryFn: async () =>
      (await accounting.from("accounts").select("*").eq("company_id", cid).order("code")).data ?? [],
  });

  const { data: existing = [] } = useQuery({
    queryKey: ["budget-entries", id],
    enabled: !!id,
    queryFn: async () =>
      (await accounting.from("budget_entries").select("*").eq("budget_id", id)).data ?? [],
  });

  const periods = useMemo(() => periodLabels(budget?.period_type ?? "monthly"), [budget?.period_type]);
  const periodCount = periods.length;

  useEffect(() => {
    if (!(accounts as any[]).length || !budget) return;
    const next: Grid = {};
    for (const a of accounts as any[]) {
      next[a.id] = Array.from({ length: periodCount }, () => "");
    }
    for (const e of existing as any[]) {
      if (next[e.account_id] !== undefined && e.period_index < periodCount) {
        next[e.account_id][e.period_index] = String(e.amount);
      }
    }
    setGrid(next);
  }, [(accounts as any[]).length, (existing as any[]).length, budget?.id, periodCount]);

  const grouped = useMemo(() => {
    const out: Record<string, any[]> = {};
    for (const a of accounts as any[]) {
      if (!out[a.type]) out[a.type] = [];
      out[a.type].push(a);
    }
    return out;
  }, [accounts]);

  const rowSum = (aid: string) => (grid[aid] ?? []).reduce((s, v) => s + (parseFloat(v) || 0), 0);
  const rowPeriod = (aid: string, i: number) => parseFloat(grid[aid]?.[i] ?? "") || 0;
  const groupPeriod = (type: string, i: number) =>
    (grouped[type] ?? []).reduce((s: number, a: any) => s + rowPeriod(a.id, i), 0);
  const groupTotal = (type: string) =>
    (grouped[type] ?? []).reduce((s: number, a: any) => s + rowSum(a.id), 0);

  const updateCell = (aid: string, idx: number, val: string) => {
    setGrid(prev => {
      const row = [...(prev[aid] ?? Array.from({ length: periodCount }, () => ""))];
      row[idx] = val;
      return { ...prev, [aid]: row };
    });
  };

  // Distribute a FY total evenly across all periods
  const distributeFYTotal = (aid: string, total: number) => {
    if (!total || periodCount === 0) return;
    const perPeriod = (total / periodCount).toFixed(2);
    setGrid(prev => ({ ...prev, [aid]: Array.from({ length: periodCount }, () => perPeriod) }));
  };

  const fillRow = (aid: string) => {
    const first = (grid[aid] ?? [])[0];
    if (!first) return toast.error("Enter Jan first");
    setGrid(prev => ({ ...prev, [aid]: Array.from({ length: periodCount }, () => first) }));
  };

  const autoFill = async () => {
    if (!budget) return;
    const year = budget.fiscal_year - 1;
    const [{ data: inv }, { data: exp }] = await Promise.all([
      accounting.from("invoices").select("total,status,issue_date").eq("company_id", cid)
        .gte("issue_date", `${year}-01-01`).lte("issue_date", `${year}-12-31`),
      accounting.from("expenses").select("amount,category,date").eq("company_id", cid)
        .gte("date", `${year}-01-01`).lte("date", `${year}-12-31`),
    ]);
    const next: Grid = {};
    for (const a of accounts as any[]) {
      next[a.id] = Array.from({ length: periodCount }, () => "");
    }
    const incomeAccs = grouped.income ?? [];
    const expAccs = grouped.expense ?? [];
    for (const i of inv ?? []) {
      if (i.status !== "paid") continue;
      const m = new Date(i.issue_date).getMonth();
      const b = budget.period_type === "monthly" ? m : budget.period_type === "quarterly" ? Math.floor(m / 3) : 0;
      const share = Number(i.total) / Math.max(incomeAccs.length, 1);
      for (const a of incomeAccs) {
        next[a.id][b] = String((parseFloat(next[a.id][b]) || 0) + share);
      }
    }
    for (const e of exp ?? []) {
      const m = new Date(e.date).getMonth();
      const b = budget.period_type === "monthly" ? m : budget.period_type === "quarterly" ? Math.floor(m / 3) : 0;
      const match = expAccs.find((a: any) => a.name.toLowerCase() === String(e.category).toLowerCase());
      if (match) next[match.id][b] = String((parseFloat(next[match.id][b]) || 0) + Number(e.amount));
    }
    const formatted: Grid = {};
    for (const [k, v] of Object.entries(next)) {
      formatted[k] = v.map(n => parseFloat(n) ? parseFloat(n).toFixed(2) : "");
    }
    setGrid(formatted);
    toast.success(`Pre-filled from ${year} actuals`);
  };

  const save = async (activate: boolean) => {
    setSaving(true);
    await accounting.from("budget_entries").delete().eq("budget_id", id);
    const rows: any[] = [];
    for (const [aid, vals] of Object.entries(grid)) {
      vals.forEach((v, idx) => {
        const n = parseFloat(v);
        if (!isNaN(n) && n !== 0) rows.push({ budget_id: id, account_id: aid, period_index: idx, amount: n });
      });
    }
    if (rows.length) {
      const { error } = await accounting.from("budget_entries").insert(rows);
      if (error) { setSaving(false); return toast.error(error.message); }
    }
    await accounting.from("budgets").update({ status: activate ? "active" : "draft" }).eq("id", id);
    setSaving(false);
    toast.success(activate ? "Budget activated" : "Saved");
    qc.invalidateQueries({ queryKey: ["budget-entries", id] });
    qc.invalidateQueries({ queryKey: ["budgets", cid] });
    if (activate) navigate(basePath);
  };

  if (bLoading) {
    return <div className="p-6 text-muted-foreground">Loading budget…</div>;
  }

  if (!budget) {
    return (
      <div className="p-6 space-y-2">
        <div className="text-muted-foreground">Budget not found (ID: {id})</div>
        <Button variant="outline" size="sm" asChild>
          <Link to={basePath}><ArrowLeft className="mr-1 h-4 w-4" /> Back to Budgets</Link>
        </Button>
      </div>
    );
  }

  const incomeTotal = groupTotal("income");
  const expenseTotal = groupTotal("expense");
  const netIncome = incomeTotal - expenseTotal;
  const fyLabel = `FY${budget.fiscal_year}`;

  return (
    <div className="space-y-4">

      {/* Header */}
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-3">
          <Button variant="ghost" size="sm" asChild>
            <Link to={basePath}><ArrowLeft className="mr-1 h-4 w-4" /> Budgets</Link>
          </Button>
          <div>
            <div className="flex items-center gap-2">
              <h1 className="text-xl font-semibold">{budget.name}</h1>
              <Badge variant={budget.status === "active" ? "default" : "secondary"}>
                {budget.status === "active" ? "Active" : "Draft"}
              </Badge>
            </div>
            <p className="text-xs text-muted-foreground">FY {budget.fiscal_year} · {budget.period_type}</p>
          </div>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" size="sm" onClick={() => save(false)} disabled={saving}>
            <Save className="h-4 w-4 mr-1" /> Save Draft
          </Button>
          <Button size="sm" onClick={() => save(true)} disabled={saving}>
            <CheckCircle2 className="h-4 w-4 mr-1" /> Activate
          </Button>
        </div>
      </div>

      {/* Tab buttons (plain, no Tabs component) */}
      <div className="flex border-b">
        {(["summary", "edit"] as const).map(t => (
          <button key={t} onClick={() => setTab(t)}
            className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px capitalize transition-colors ${tab === t ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`}>
            {t === "summary" ? "Summary" : "Edit Budget"}
          </button>
        ))}
      </div>

      {/* Summary */}
      {tab === "summary" && (
        <div className="space-y-4">
          <Card>
            <CardContent className="p-0 overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="bg-muted/50 border-b">
                    <th className="text-left font-semibold py-2.5 px-4 min-w-[160px]">TOTALS</th>
                    {periods.map(p => <th key={p} className="text-right font-semibold py-2.5 px-3 min-w-[68px]">{p}</th>)}
                    <th className="text-right font-bold py-2.5 px-4 min-w-[90px] bg-muted/80">{fyLabel}</th>
                  </tr>
                </thead>
                <tbody>
                  <tr className="border-b">
                    <td className="py-2.5 px-4 font-medium">Expense</td>
                    {periods.map((_, i) => <td key={i} className="py-2.5 px-3 text-right tabular-nums">{groupPeriod("expense", i).toFixed(2)}</td>)}
                    <td className="py-2.5 px-4 text-right font-semibold bg-muted/30">{money(expenseTotal, cur)}</td>
                  </tr>
                  <tr className="border-b">
                    <td className="py-2.5 px-4 font-medium">Income</td>
                    {periods.map((_, i) => <td key={i} className="py-2.5 px-3 text-right tabular-nums">{groupPeriod("income", i).toFixed(2)}</td>)}
                    <td className="py-2.5 px-4 text-right font-semibold bg-muted/30">{money(incomeTotal, cur)}</td>
                  </tr>
                  <tr className="bg-muted/30 font-bold">
                    <td className="py-2.5 px-4">Net Income</td>
                    {periods.map((_, i) => {
                      const net = groupPeriod("income", i) - groupPeriod("expense", i);
                      return <td key={i} className={`py-2.5 px-3 text-right tabular-nums ${net < 0 ? "text-red-600" : ""}`}>{net.toFixed(2)}</td>;
                    })}
                    <td className={`py-2.5 px-4 text-right font-bold bg-muted/50 ${netIncome < 0 ? "text-red-600" : ""}`}>{money(netIncome, cur)}</td>
                  </tr>
                </tbody>
              </table>
            </CardContent>
          </Card>

          <div className="flex border-b">
            {(["income", "expense"] as const).map(s => (
              <button key={s} onClick={() => setSummarySection(s)}
                className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px capitalize transition-colors ${summarySection === s ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`}>
                {s === "income" ? "Income" : "Expenses"}
              </button>
            ))}
          </div>

          <Card>
            <CardContent className="p-0 overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="bg-muted/50 border-b">
                    <th className="text-left font-semibold py-2.5 px-4 min-w-[200px]">{summarySection.toUpperCase()}</th>
                    {periods.map(p => <th key={p} className="text-right font-semibold py-2.5 px-3 min-w-[68px]">{p}</th>)}
                    <th className="text-right font-bold py-2.5 px-4 min-w-[90px] bg-muted/80">{fyLabel}</th>
                  </tr>
                </thead>
                <tbody>
                  {(grouped[summarySection] ?? []).map((a: any) => {
                    const total = rowSum(a.id);
                    return (
                      <tr key={a.id} className="border-b hover:bg-muted/20">
                        <td className="py-2.5 px-4 font-semibold">{a.code ? `${a.code} ${a.name}` : a.name}</td>
                        {periods.map((_, i) => (
                          <td key={i} className="py-2.5 px-3 text-right tabular-nums">
                            {rowPeriod(a.id, i) > 0 ? rowPeriod(a.id, i).toFixed(2) : "—"}
                          </td>
                        ))}
                        <td className="py-2.5 px-4 text-right font-semibold bg-muted/30">{money(total, cur)}</td>
                      </tr>
                    );
                  })}
                  {(grouped[summarySection] ?? []).length === 0 && (
                    <tr>
                      <td colSpan={periods.length + 2} className="text-center text-muted-foreground py-6 text-sm">
                        No {summarySection} accounts yet. Add them in Chart of Accounts.
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </CardContent>
          </Card>
        </div>
      )}

      {/* Edit */}
      {tab === "edit" && (
        <div className="space-y-4">
          <Card>
            <CardContent className="flex flex-wrap items-center gap-4 py-3">
              <Button variant="outline" size="sm" onClick={autoFill}>
                <Wand2 className="mr-1 h-4 w-4" /> Auto-fill from Prior Year
              </Button>
              <div className="flex items-center gap-2 ml-auto">
                <Switch id="hz" checked={hideZero} onCheckedChange={setHideZero} />
                <Label htmlFor="hz" className="text-sm">Hide zero accounts</Label>
              </div>
            </CardContent>
          </Card>

          {(["income", "expense"] as const).map(type => {
            const accs = grouped[type] ?? [];
            const isOpen = expanded[type];
            return (
              <Card key={type}>
                <div className="flex items-center justify-between px-4 py-3 border-b bg-muted/40 cursor-pointer"
                  onClick={() => setExpanded(p => ({ ...p, [type]: !p[type] }))}>
                  <div className="flex items-center gap-2 font-semibold">
                    {isOpen ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
                    {type === "income" ? "Income" : "Expenses"}
                    <span className="text-xs font-normal text-muted-foreground ml-1">({accs.length})</span>
                  </div>
                  <div className="text-sm font-semibold">{money(groupTotal(type), cur)}</div>
                </div>
                {isOpen && (
                  <CardContent className="p-0 overflow-x-auto">
                    <table className="w-full text-sm">
                      <thead>
                        <tr className="bg-muted/20 border-b">
                          <th className="text-left font-medium py-2 px-4 min-w-[200px]">Account</th>
                          {periods.map(p => <th key={p} className="text-right font-medium py-2 px-2 min-w-[72px]">{p}</th>)}
                          <th className="text-right font-medium py-2 px-4 min-w-[88px] bg-muted/40">{fyLabel}</th>
                          <th className="w-8"></th>
                        </tr>
                      </thead>
                      <tbody>
                        {accs.map((a: any) => {
                          const total = rowSum(a.id);
                          if (hideZero && total === 0) return null;
                          return (
                            <tr key={a.id} className="border-b hover:bg-muted/10">
                              <td className="py-1.5 px-4 font-medium">{a.code ? `${a.code} ${a.name}` : a.name}</td>
                              {periods.map((_, idx) => (
                                <td key={idx} className="py-1 px-1">
                                  <Input
                                    type="number"
                                    inputMode="decimal"
                                    value={grid[a.id]?.[idx] ?? ""}
                                    onChange={e => updateCell(a.id, idx, e.target.value)}
                                    className="h-7 text-right tabular-nums px-2 text-xs"
                                    placeholder="0.00"
                                  />
                                </td>
                              ))}
                              <td className="py-1 px-1 bg-muted/20">
                                <Input
                                  type="number"
                                  inputMode="decimal"
                                  placeholder={money(total, cur)}
                                  className="h-7 text-right tabular-nums px-2 text-xs bg-muted/10 border-dashed"
                                  title="Enter FY total to distribute evenly across all periods"
                                  onBlur={(e) => {
                                    const v = parseFloat(e.target.value);
                                    if (v > 0) { distributeFYTotal(a.id, v); e.target.value = ""; }
                                  }}
                                  onKeyDown={(e) => {
                                    if (e.key === "Enter") {
                                      const v = parseFloat((e.target as HTMLInputElement).value);
                                      if (v > 0) { distributeFYTotal(a.id, v); (e.target as HTMLInputElement).value = ""; }
                                    }
                                  }}
                                />
                              </td>
                              <td className="px-1">
                                <Button size="icon" variant="ghost" className="h-6 w-6" onClick={() => fillRow(a.id)}>
                                  <MoveRight className="h-3 w-3" />
                                </Button>
                              </td>
                            </tr>
                          );
                        })}
                        {accs.length === 0 && (
                          <tr>
                            <td colSpan={periods.length + 3} className="text-center text-muted-foreground py-4 text-xs">
                              No accounts. Add them in Chart of Accounts first.
                            </td>
                          </tr>
                        )}
                        {accs.length > 0 && (
                          <tr className="bg-muted/30 font-semibold border-t">
                            <td className="py-2 px-4">Total</td>
                            {periods.map((_, i) => (
                              <td key={i} className="py-2 px-2 text-right tabular-nums text-xs">{money(groupPeriod(type, i), cur)}</td>
                            ))}
                            <td className="py-2 px-4 text-right tabular-nums bg-muted/50">{money(groupTotal(type), cur)}</td>
                            <td></td>
                          </tr>
                        )}
                      </tbody>
                    </table>
                  </CardContent>
                )}
              </Card>
            );
          })}

          <div className="flex items-center justify-between rounded-lg border bg-muted/30 px-6 py-3 font-semibold">
            <span>Net Income</span>
            <span className={netIncome < 0 ? "text-red-600" : ""}>{money(netIncome, cur)}</span>
          </div>
        </div>
      )}

    </div>
  );
}
