import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { PieChart, Download, Printer } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

type ReportType = "trial_balance" | "income_statement" | "balance_sheet" | "aging" | "delinquency";

export default function AccountingReportsPage({ associationIds }: { associationIds?: string[] } = {}) {
  const { toast } = useToast();
  const [associations, setAssociations] = useState<any[]>([]);
  const [selectedAssocId, setSelectedAssocId] = useState("");
  const [startDate, setStartDate] = useState(new Date(new Date().getFullYear(), 0, 1).toISOString().split("T")[0]);
  const [endDate, setEndDate] = useState(new Date().toISOString().split("T")[0]);
  const [reportType, setReportType] = useState<ReportType>("trial_balance");

  // Data
  const [accounts, setAccounts] = useState<any[]>([]);
  const [journalEntries, setJournalEntries] = useState<any[]>([]);
  const [ownerLedger, setOwnerLedger] = useState<any[]>([]);
  const [owners, setOwners] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    let q = supabase.from("associations").select("id, name").eq("status", "active").order("name");
    // When scoped (e.g. board members), limit the picker to the given associations.
    if (associationIds?.length) q = q.in("id", associationIds);
    q.then(({ data }) => {
      setAssociations(data || []);
      if (data?.length) setSelectedAssocId(data[0].id);
    });
  }, [associationIds?.join(",")]);

  const generateReport = async () => {
    if (!selectedAssocId) return;
    setLoading(true);
    const [acctRes, jeRes, olRes, oRes] = await Promise.all([
      supabase.from("chart_of_accounts").select("*").eq("association_id", selectedAssocId).order("account_number"),
      supabase.from("journal_entries").select("*, chart_of_accounts(account_number, account_name, account_type)").eq("association_id", selectedAssocId).gte("date", startDate).lte("date", endDate),
      supabase.from("owner_ledger_entries").select("*, owners(first_name, last_name), units(unit_number)").eq("association_id", selectedAssocId),
      supabase.from("owners").select("id, first_name, last_name, balance, unit_id, units(unit_number)").eq("status", "active").eq("association_id", selectedAssocId).order("last_name"),
    ]);
    setAccounts(acctRes.data || []);
    setJournalEntries(jeRes.data || []);
    setOwnerLedger(olRes.data || []);
    setOwners(oRes.data || []);
    setLoading(false);
  };

  // Trial Balance
  const trialBalance = useMemo(() => {
    const map = new Map<string, { account: any; debit: number; credit: number }>();
    journalEntries.forEach(je => {
      const key = je.chart_of_account_id || "uncategorized";
      if (!map.has(key)) {
        map.set(key, {
          account: je.chart_of_accounts || { account_number: "N/A", account_name: "Uncategorized", account_type: "expense" },
          debit: 0, credit: 0
        });
      }
      const entry = map.get(key)!;
      if (je.type === "debit") entry.debit += Number(je.amount);
      else entry.credit += Number(je.amount);
    });
    return Array.from(map.values()).sort((a, b) => (a.account.account_number || "").localeCompare(b.account.account_number || ""));
  }, [journalEntries]);

  // Income Statement
  const incomeStatement = useMemo(() => {
    const income: typeof trialBalance = [];
    const expenses: typeof trialBalance = [];
    trialBalance.forEach(tb => {
      if (tb.account.account_type === "income") income.push(tb);
      else if (tb.account.account_type === "expense") expenses.push(tb);
    });
    const totalIncome = income.reduce((s, i) => s + i.credit - i.debit, 0);
    const totalExpenses = expenses.reduce((s, e) => s + e.debit - e.credit, 0);
    return { income, expenses, totalIncome, totalExpenses, netIncome: totalIncome - totalExpenses };
  }, [trialBalance]);

  // Balance Sheet
  const balanceSheet = useMemo(() => {
    const assets: typeof trialBalance = [];
    const liabilities: typeof trialBalance = [];
    const equity: typeof trialBalance = [];
    trialBalance.forEach(tb => {
      if (tb.account.account_type === "asset") assets.push(tb);
      else if (tb.account.account_type === "liability") liabilities.push(tb);
      else if (tb.account.account_type === "equity") equity.push(tb);
    });
    return {
      assets, liabilities, equity,
      totalAssets: assets.reduce((s, a) => s + a.debit - a.credit, 0),
      totalLiabilities: liabilities.reduce((s, l) => s + l.credit - l.debit, 0),
      totalEquity: equity.reduce((s, e) => s + e.credit - e.debit, 0),
    };
  }, [trialBalance]);

  // Aging Report
  const agingReport = useMemo(() => {
    const now = new Date();
    return owners.filter(o => Number(o.balance) > 0).map(o => {
      const entries = ownerLedger.filter(e => e.owner_id === o.id && Number(e.debit) > 0);
      let current = 0, over30 = 0, over60 = 0, over90 = 0;
      entries.forEach(e => {
        const days = Math.floor((now.getTime() - new Date(e.date).getTime()) / 86400000);
        const amt = Number(e.debit) - Number(e.credit);
        if (amt <= 0) return;
        if (days <= 30) current += amt;
        else if (days <= 60) over30 += amt;
        else if (days <= 90) over60 += amt;
        else over90 += amt;
      });
      return { owner: o, current, over30, over60, over90, total: Number(o.balance) };
    }).sort((a, b) => b.total - a.total);
  }, [owners, ownerLedger]);

  const fmtMoney = (v: number) => `$${v.toLocaleString("en-US", { minimumFractionDigits: 2 })}`;

  return (
    <div className="space-y-6">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-foreground flex items-center gap-2"><PieChart className="h-6 w-6 text-primary" /> Financial Reports</h1>
          <p className="text-sm text-muted-foreground mt-1">Generate accounting and owner reports.</p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" onClick={() => window.print()} className="gap-2"><Printer className="h-4 w-4" /> Print</Button>
        </div>
      </div>

      {/* Filters */}
      <Card>
        <CardContent className="pt-6">
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            <div>
              <Label className="text-xs font-semibold text-muted-foreground uppercase">Association</Label>
              <Select value={selectedAssocId} onValueChange={setSelectedAssocId}>
                <SelectTrigger><SelectValue placeholder="Select" /></SelectTrigger>
                <SelectContent>{associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}</SelectContent>
              </Select>
            </div>
            <div><Label className="text-xs font-semibold text-muted-foreground uppercase">Start Date</Label><Input type="date" value={startDate} onChange={e => setStartDate(e.target.value)} /></div>
            <div><Label className="text-xs font-semibold text-muted-foreground uppercase">End Date</Label><Input type="date" value={endDate} onChange={e => setEndDate(e.target.value)} /></div>
            <div className="flex items-end"><Button onClick={generateReport} className="w-full" disabled={loading}>{loading ? "Generating..." : "Generate Report"}</Button></div>
          </div>
        </CardContent>
      </Card>

      <Tabs value={reportType} onValueChange={(v) => setReportType(v as ReportType)}>
        <TabsList>
          <TabsTrigger value="trial_balance">Trial Balance</TabsTrigger>
          <TabsTrigger value="income_statement">Income Statement</TabsTrigger>
          <TabsTrigger value="balance_sheet">Balance Sheet</TabsTrigger>
          <TabsTrigger value="aging">Aging Report</TabsTrigger>
          <TabsTrigger value="delinquency">Delinquency</TabsTrigger>
        </TabsList>

        <TabsContent value="trial_balance">
          <Card>
            <CardHeader><CardTitle>Trial Balance</CardTitle></CardHeader>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Account #</TableHead><TableHead>Account Name</TableHead><TableHead>Type</TableHead>
                  <TableHead className="text-right">Debit</TableHead><TableHead className="text-right">Credit</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {trialBalance.map((tb, i) => (
                  <TableRow key={i}>
                    <TableCell className="font-mono">{tb.account.account_number}</TableCell>
                    <TableCell className="font-medium">{tb.account.account_name}</TableCell>
                    <TableCell className="capitalize">{tb.account.account_type}</TableCell>
                    <TableCell className="text-right font-mono">{tb.debit > 0 ? fmtMoney(tb.debit) : "—"}</TableCell>
                    <TableCell className="text-right font-mono">{tb.credit > 0 ? fmtMoney(tb.credit) : "—"}</TableCell>
                  </TableRow>
                ))}
                {trialBalance.length > 0 && (
                  <TableRow className="font-bold border-t-2">
                    <TableCell colSpan={3}>Totals</TableCell>
                    <TableCell className="text-right font-mono">{fmtMoney(trialBalance.reduce((s, t) => s + t.debit, 0))}</TableCell>
                    <TableCell className="text-right font-mono">{fmtMoney(trialBalance.reduce((s, t) => s + t.credit, 0))}</TableCell>
                  </TableRow>
                )}
                {trialBalance.length === 0 && <TableRow><TableCell colSpan={5} className="text-center py-8 text-muted-foreground">Generate a report to see data.</TableCell></TableRow>}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>

        <TabsContent value="income_statement">
          <Card>
            <CardHeader><CardTitle>Income Statement (P&L)</CardTitle></CardHeader>
            <Table>
              <TableHeader><TableRow><TableHead>Account</TableHead><TableHead className="text-right">Amount</TableHead></TableRow></TableHeader>
              <TableBody>
                <TableRow className="bg-muted/50"><TableCell colSpan={2} className="font-bold">Revenue</TableCell></TableRow>
                {incomeStatement.income.map((i, idx) => (
                  <TableRow key={idx}><TableCell className="pl-8">{i.account.account_name}</TableCell><TableCell className="text-right font-mono">{fmtMoney(i.credit - i.debit)}</TableCell></TableRow>
                ))}
                <TableRow className="font-bold border-t"><TableCell>Total Revenue</TableCell><TableCell className="text-right font-mono text-emerald-600">{fmtMoney(incomeStatement.totalIncome)}</TableCell></TableRow>
                <TableRow className="bg-muted/50"><TableCell colSpan={2} className="font-bold">Expenses</TableCell></TableRow>
                {incomeStatement.expenses.map((e, idx) => (
                  <TableRow key={idx}><TableCell className="pl-8">{e.account.account_name}</TableCell><TableCell className="text-right font-mono">{fmtMoney(e.debit - e.credit)}</TableCell></TableRow>
                ))}
                <TableRow className="font-bold border-t"><TableCell>Total Expenses</TableCell><TableCell className="text-right font-mono text-destructive">{fmtMoney(incomeStatement.totalExpenses)}</TableCell></TableRow>
                <TableRow className="font-bold border-t-2 text-lg">
                  <TableCell>Net Income</TableCell>
                  <TableCell className={`text-right font-mono ${incomeStatement.netIncome >= 0 ? "text-emerald-600" : "text-destructive"}`}>{fmtMoney(incomeStatement.netIncome)}</TableCell>
                </TableRow>
                {journalEntries.length === 0 && <TableRow><TableCell colSpan={2} className="text-center py-8 text-muted-foreground">Generate a report to see data.</TableCell></TableRow>}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>

        <TabsContent value="balance_sheet">
          <Card>
            <CardHeader><CardTitle>Balance Sheet</CardTitle></CardHeader>
            <Table>
              <TableHeader><TableRow><TableHead>Account</TableHead><TableHead className="text-right">Amount</TableHead></TableRow></TableHeader>
              <TableBody>
                <TableRow className="bg-muted/50"><TableCell colSpan={2} className="font-bold">Assets</TableCell></TableRow>
                {balanceSheet.assets.map((a, i) => (
                  <TableRow key={i}><TableCell className="pl-8">{a.account.account_name}</TableCell><TableCell className="text-right font-mono">{fmtMoney(a.debit - a.credit)}</TableCell></TableRow>
                ))}
                <TableRow className="font-bold border-t"><TableCell>Total Assets</TableCell><TableCell className="text-right font-mono">{fmtMoney(balanceSheet.totalAssets)}</TableCell></TableRow>
                <TableRow className="bg-muted/50"><TableCell colSpan={2} className="font-bold">Liabilities</TableCell></TableRow>
                {balanceSheet.liabilities.map((l, i) => (
                  <TableRow key={i}><TableCell className="pl-8">{l.account.account_name}</TableCell><TableCell className="text-right font-mono">{fmtMoney(l.credit - l.debit)}</TableCell></TableRow>
                ))}
                <TableRow className="font-bold border-t"><TableCell>Total Liabilities</TableCell><TableCell className="text-right font-mono">{fmtMoney(balanceSheet.totalLiabilities)}</TableCell></TableRow>
                <TableRow className="bg-muted/50"><TableCell colSpan={2} className="font-bold">Equity</TableCell></TableRow>
                {balanceSheet.equity.map((e, i) => (
                  <TableRow key={i}><TableCell className="pl-8">{e.account.account_name}</TableCell><TableCell className="text-right font-mono">{fmtMoney(e.credit - e.debit)}</TableCell></TableRow>
                ))}
                <TableRow className="font-bold border-t"><TableCell>Total Equity</TableCell><TableCell className="text-right font-mono">{fmtMoney(balanceSheet.totalEquity)}</TableCell></TableRow>
                {journalEntries.length === 0 && <TableRow><TableCell colSpan={2} className="text-center py-8 text-muted-foreground">Generate a report to see data.</TableCell></TableRow>}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>

        <TabsContent value="aging">
          <Card>
            <CardHeader><CardTitle>Aging Report</CardTitle></CardHeader>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Owner</TableHead><TableHead>Unit</TableHead>
                  <TableHead className="text-right">Current</TableHead><TableHead className="text-right">31-60</TableHead>
                  <TableHead className="text-right">61-90</TableHead><TableHead className="text-right">90+</TableHead>
                  <TableHead className="text-right">Total</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {agingReport.length === 0 ? (
                  <TableRow><TableCell colSpan={7} className="text-center py-8 text-muted-foreground">No delinquent accounts.</TableCell></TableRow>
                ) : agingReport.map((r, i) => (
                  <TableRow key={i}>
                    <TableCell className="font-medium">{r.owner.last_name}, {r.owner.first_name}</TableCell>
                    <TableCell>{r.owner.units?.unit_number || "—"}</TableCell>
                    <TableCell className="text-right font-mono">{r.current > 0 ? fmtMoney(r.current) : "—"}</TableCell>
                    <TableCell className="text-right font-mono">{r.over30 > 0 ? fmtMoney(r.over30) : "—"}</TableCell>
                    <TableCell className="text-right font-mono">{r.over60 > 0 ? fmtMoney(r.over60) : "—"}</TableCell>
                    <TableCell className="text-right font-mono text-destructive">{r.over90 > 0 ? fmtMoney(r.over90) : "—"}</TableCell>
                    <TableCell className="text-right font-mono font-bold">{fmtMoney(r.total)}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>

        <TabsContent value="delinquency">
          <Card>
            <CardHeader><CardTitle>Delinquency Report</CardTitle></CardHeader>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Owner</TableHead><TableHead>Unit</TableHead>
                  <TableHead className="text-right">Balance Due</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {owners.filter(o => Number(o.balance) > 0).length === 0 ? (
                  <TableRow><TableCell colSpan={3} className="text-center py-8 text-muted-foreground">No delinquent accounts.</TableCell></TableRow>
                ) : owners.filter(o => Number(o.balance) > 0).sort((a, b) => Number(b.balance) - Number(a.balance)).map((o, i) => (
                  <TableRow key={i}>
                    <TableCell className="font-medium">{o.last_name}, {o.first_name}</TableCell>
                    <TableCell>{o.units?.unit_number || "—"}</TableCell>
                    <TableCell className="text-right font-mono font-bold text-destructive">{fmtMoney(Number(o.balance))}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
}
