import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { accounting } from "@/lib/accountingClient";
import { supabase } from "@/integrations/supabase/client";
import { useCompanyId } from "./lib/useCompanyId";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { money, fmtDate } from "./lib/format";
import { generateDashboardPdf } from "./lib/dashboardPdf";

type RangePreset = "this-month" | "this-quarter" | "ytd" | "last-6-months" | "custom";

function presetRange(p: RangePreset): { from: string; to: string } {
  const now = new Date();
  const y = now.getFullYear();
  const iso = (d: Date) => d.toISOString().slice(0, 10);
  const today = iso(now);
  switch (p) {
    case "this-month":   return { from: iso(new Date(y, now.getMonth(), 1)), to: today };
    case "this-quarter": return { from: iso(new Date(y, Math.floor(now.getMonth() / 3) * 3, 1)), to: today };
    case "ytd":          return { from: `${y}-01-01`, to: today };
    case "custom":       return { from: `${y}-01-01`, to: today };
    case "last-6-months":
    default: {
      const s = new Date(y, now.getMonth() - 5, 1);
      return { from: iso(s), to: today };
    }
  }
}
import {
  Receipt, FileText, Landmark, ArrowUpRight, ArrowDownRight, Loader2, FileDown,
} from "lucide-react";
import {
  BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid,
  PieChart, Pie, Cell, Legend,
} from "recharts";

const DONUT_COLORS = ["#00897B", "#26A69A", "#F59E0B", "#EF4444", "#6366F1", "#8B5CF6"];

export default function AccountingDashboardPage({ association }: { association?: { id: string; name?: string } | null } = {}) {
  const { companyId, loading: companyLoading, error: companyError, associationId, associationName } = useCompanyId(association);
  const cid = companyId ?? "";
  const c = "USD";

  const { data: assocMeta } = useQuery({
    queryKey: ["assoc-logo", associationId],
    enabled: !!associationId,
    queryFn: async () => (await supabase.from("associations").select("logo_url").eq("id", associationId!).maybeSingle()).data,
  });
  const logoUrl = (assocMeta as any)?.logo_url || null;
  const [exporting, setExporting] = useState(false);

  // Date range for the charts + recent transactions (receivables/payables/cash
  // remain current snapshots — they are point-in-time by nature).
  const [preset, setPreset] = useState<RangePreset>("last-6-months");
  const [range, setRange] = useState(() => presetRange("last-6-months"));
  const from = range.from;
  const to = range.to;
  const applyPreset = (p: RangePreset) => { setPreset(p); if (p !== "custom") setRange(presetRange(p)); };
  const rangeLabel = `${fmtDate(from)} – ${fmtDate(to)}`;

  const { data } = useQuery({
    queryKey: ["dashboard", cid, from, to],
    enabled: !!cid,
    queryFn: async () => {
      const [inv, bills, tx, acc] = await Promise.all([
        accounting.from("invoices").select("total,status,issue_date").eq("company_id", cid),
        accounting.from("bills").select("total,status,issue_date").eq("company_id", cid),
        accounting
          .from("transactions")
          .select("amount,type,date,description,category,reference")
          .eq("company_id", cid)
          .gte("date", from)
          .lte("date", to)
          .order("date", { ascending: false })
          .limit(50),
        accounting.from("accounts").select("balance,is_bank").eq("company_id", cid),
      ]);

      const invoices = inv.data ?? [];
      const billsArr = bills.data ?? [];
      const txAll = tx.data ?? [];

      const totalReceivable = invoices
        .filter((i) => i.status !== "paid" && i.status !== "void")
        .reduce((s, i) => s + Number(i.total), 0);
      const totalPayable = billsArr
        .filter((b) => b.status !== "paid" && b.status !== "void")
        .reduce((s, b) => s + Number(b.total), 0);
      const cash = (acc.data ?? [])
        .filter((a) => a.is_bank)
        .reduce((s, a) => s + Number(a.balance), 0);

      // Invoice status counts
      const counts = { draft: 0, sent: 0, overdue: 0, paid: 0 };
      for (const i of invoices) {
        if (i.status === "paid") counts.paid++;
        else if (i.status === "draft") counts.draft++;
        else if (i.status === "void") continue;
        else {
          if ((i as any).status === "overdue") counts.overdue++;
          else counts.sent++;
        }
      }

      // Income/expense by month across the selected range
      const months: { key: string; label: string; income: number; expense: number }[] = [];
      const cursor = new Date(`${from}T00:00:00`);
      cursor.setDate(1);
      const lastMonth = new Date(`${to}T00:00:00`);
      lastMonth.setDate(1);
      while (cursor <= lastMonth && months.length < 36) {
        months.push({
          key: `${cursor.getFullYear()}-${String(cursor.getMonth() + 1).padStart(2, "0")}`,
          label: cursor.toLocaleString("en-US", { month: "short", year: "2-digit" }),
          income: 0,
          expense: 0,
        });
        cursor.setMonth(cursor.getMonth() + 1);
      }
      const bucket = (date: string) => date.slice(0, 7);
      const inWin = (d?: string | null) => !!d && d >= from && d <= to;
      for (const i of invoices) {
        if (inWin(i.issue_date)) {
          const m = months.find((x) => x.key === bucket(i.issue_date!));
          if (m) m.income += Number(i.total);
        }
      }
      for (const b of billsArr) {
        if (inWin(b.issue_date)) {
          const m = months.find((x) => x.key === bucket(b.issue_date!));
          if (m) m.expense += Number(b.total);
        }
      }

      // Top expenses by category (from debit transactions)
      const catMap = new Map<string, number>();
      for (const t of txAll) {
        if (t.type === "debit") {
          const key = t.category || "Uncategorized";
          catMap.set(key, (catMap.get(key) ?? 0) + Number(t.amount));
        }
      }
      const topExpenses = Array.from(catMap.entries())
        .map(([name, value]) => ({ name, value }))
        .sort((a, b) => b.value - a.value)
        .slice(0, 6);

      return {
        totalReceivable,
        totalPayable,
        cash,
        counts,
        months,
        topExpenses,
        recent: txAll.slice(0, 15),
      };
    },
  });

  const summary = [
    {
      label: "Total Receivables",
      value: money(data?.totalReceivable, c),
      icon: FileText,
      accent: "bg-blue-50 text-blue-600 ring-blue-100",
      bar: "from-blue-500/10 to-transparent",
      trend: "Outstanding",
      TrendIcon: ArrowUpRight,
    },
    {
      label: "Total Payables",
      value: money(data?.totalPayable, c),
      icon: Receipt,
      accent: "bg-orange-50 text-orange-600 ring-orange-100",
      bar: "from-orange-500/10 to-transparent",
      trend: "Owed",
      TrendIcon: ArrowDownRight,
    },
    {
      label: "Bank Balance",
      value: money(data?.cash, c),
      icon: Landmark,
      accent: "bg-emerald-50 text-emerald-600 ring-emerald-100",
      bar: "from-emerald-500/10 to-transparent",
      trend: "All accounts",
      TrendIcon: ArrowUpRight,
    },
  ];

  const invoiceTiles = [
    { label: "Draft", value: data?.counts.draft ?? 0, dot: "bg-slate-400", badge: "bg-slate-100 text-slate-700" },
    { label: "Sent", value: data?.counts.sent ?? 0, dot: "bg-blue-500", badge: "bg-blue-100 text-blue-700" },
    { label: "Overdue", value: data?.counts.overdue ?? 0, dot: "bg-red-500", badge: "bg-red-100 text-red-700" },
    { label: "Paid", value: data?.counts.paid ?? 0, dot: "bg-emerald-500", badge: "bg-emerald-100 text-emerald-700" },
  ];

  if (!associationId) return <p className="text-sm text-muted-foreground">Select an association.</p>;
  if (companyLoading) return <div className="flex justify-center py-12"><Loader2 className="h-6 w-6 animate-spin text-muted-foreground" /></div>;
  if (companyError || !companyId) return <p className="text-sm text-muted-foreground text-center py-12">{companyError || "Accounting setup is not ready."}</p>;

  return (
    <div className="space-y-6">
      <div className="flex items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Dashboard</h1>
          <p className="text-sm text-muted-foreground">{associationName} · {rangeLabel}</p>
        </div>
        <div className="flex items-center gap-2 flex-wrap justify-end">
          <Select value={preset} onValueChange={(v) => applyPreset(v as RangePreset)}>
            <SelectTrigger className="h-9 w-[150px]"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="this-month">This Month</SelectItem>
              <SelectItem value="this-quarter">This Quarter</SelectItem>
              <SelectItem value="ytd">Year to Date</SelectItem>
              <SelectItem value="last-6-months">Last 6 Months</SelectItem>
              <SelectItem value="custom">Custom</SelectItem>
            </SelectContent>
          </Select>
          {preset === "custom" && (
            <div className="flex items-center gap-1">
              <Input type="date" value={from} className="h-9 w-[140px]"
                onChange={(e) => setRange((r) => ({ ...r, from: e.target.value }))} />
              <span className="text-muted-foreground text-xs">to</span>
              <Input type="date" value={to} className="h-9 w-[140px]"
                onChange={(e) => setRange((r) => ({ ...r, to: e.target.value }))} />
            </div>
          )}
          <Button
            variant="outline"
            size="sm"
            className="gap-1"
            disabled={!data || exporting}
            onClick={async () => {
              if (!data) return;
              setExporting(true);
              try {
                await generateDashboardPdf({ companyName: associationName ?? "Company", logoUrl, currency: c, data, rangeLabel });
              } finally {
                setExporting(false);
              }
            }}
          >
            {exporting ? <Loader2 className="h-4 w-4 animate-spin" /> : <FileDown className="h-4 w-4" />} Export PDF
          </Button>
        </div>
      </div>

      {/* Cash flow summary */}
      <div className="grid gap-4 md:grid-cols-3">
        {summary.map((s) => (
          <Card key={s.label} className="relative overflow-hidden border-border/60 shadow-sm">
            <div className={`pointer-events-none absolute inset-x-0 top-0 h-20 bg-gradient-to-b ${s.bar}`} />
            <CardContent className="relative p-5">
              <div className="flex items-start justify-between">
                <div>
                  <p className="text-sm font-medium text-muted-foreground">{s.label}</p>
                  <p className="mt-2 text-2xl font-semibold tracking-tight">{s.value}</p>
                </div>
                <div className={`flex h-10 w-10 items-center justify-center rounded-lg ring-1 ${s.accent}`}>
                  <s.icon className="h-5 w-5" />
                </div>
              </div>
              <div className="mt-4 flex items-center gap-1 text-xs text-muted-foreground">
                <s.TrendIcon className="h-3.5 w-3.5" />
                {s.trend}
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      {/* Charts row */}
      <div className="grid gap-4 lg:grid-cols-3">
        <Card className="border-border/60 shadow-sm lg:col-span-2">
          <CardHeader>
            <CardTitle className="text-base">Income & Expenses</CardTitle>
            <p className="text-xs text-muted-foreground">Last 6 months</p>
          </CardHeader>
          <CardContent className="h-72">
            <ResponsiveContainer width="100%" height="100%">
              <BarChart data={data?.months ?? []} margin={{ top: 8, right: 8, left: -10, bottom: 0 }}>
                <CartesianGrid strokeDasharray="3 3" stroke="#E5E7EB" vertical={false} />
                <XAxis dataKey="label" tickLine={false} axisLine={false} fontSize={12} stroke="#6B7280" />
                <YAxis tickLine={false} axisLine={false} fontSize={12} stroke="#6B7280" />
                <Tooltip
                  cursor={{ fill: "rgba(0,137,123,0.06)" }}
                  contentStyle={{ borderRadius: 8, border: "1px solid #E5E7EB", fontSize: 12 }}
                  formatter={(v: number) => money(v, c)}
                />
                <Legend wrapperStyle={{ fontSize: 12 }} iconType="circle" />
                <Bar dataKey="income" name="Income" fill="#00897B" radius={[4, 4, 0, 0]} />
                <Bar dataKey="expense" name="Expenses" fill="#F59E0B" radius={[4, 4, 0, 0]} />
              </BarChart>
            </ResponsiveContainer>
          </CardContent>
        </Card>

        <Card className="border-border/60 shadow-sm">
          <CardHeader>
            <CardTitle className="text-base">Top Expenses</CardTitle>
            <p className="text-xs text-muted-foreground">By category</p>
          </CardHeader>
          <CardContent className="h-72">
            {(data?.topExpenses?.length ?? 0) === 0 ? (
              <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
                No expenses yet
              </div>
            ) : (
              <ResponsiveContainer width="100%" height="100%">
                <PieChart>
                  <Pie
                    data={data!.topExpenses}
                    dataKey="value"
                    nameKey="name"
                    innerRadius={55}
                    outerRadius={85}
                    paddingAngle={2}
                  >
                    {data!.topExpenses.map((_, i) => (
                      <Cell key={i} fill={DONUT_COLORS[i % DONUT_COLORS.length]} />
                    ))}
                  </Pie>
                  <Tooltip
                    contentStyle={{ borderRadius: 8, border: "1px solid #E5E7EB", fontSize: 12 }}
                    formatter={(v: number) => money(v, c)}
                  />
                  <Legend wrapperStyle={{ fontSize: 11 }} iconType="circle" />
                </PieChart>
              </ResponsiveContainer>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Invoices overview */}
      <Card className="border-border/60 shadow-sm">
        <CardHeader>
          <CardTitle className="text-base">Invoices Overview</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            {invoiceTiles.map((t) => (
              <div
                key={t.label}
                className="flex items-center justify-between rounded-lg border border-border/60 bg-background p-4"
              >
                <div className="flex items-center gap-3">
                  <span className={`h-2.5 w-2.5 rounded-full ${t.dot}`} />
                  <span className="text-sm font-medium">{t.label}</span>
                </div>
                <Badge variant="secondary" className={`${t.badge} border-0 font-semibold`}>
                  {t.value}
                </Badge>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>

      {/* Recent Transactions */}
      <Card className="border-border/60 shadow-sm">
        <CardHeader>
          <CardTitle className="text-base">Recent Transactions</CardTitle>
        </CardHeader>
        <CardContent className="p-0">
          {(data?.recent?.length ?? 0) === 0 ? (
            <p className="px-6 py-8 text-sm text-muted-foreground">No transactions yet.</p>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead className="bg-muted/40 text-xs uppercase tracking-wider text-muted-foreground">
                  <tr>
                    <th className="px-6 py-3 text-left font-medium">Date</th>
                    <th className="px-6 py-3 text-left font-medium">Description</th>
                    <th className="px-6 py-3 text-left font-medium">Category</th>
                    <th className="px-6 py-3 text-left font-medium">Reference</th>
                    <th className="px-6 py-3 text-right font-medium">Amount</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-border/60">
                  {data!.recent.map((t: any, i: number) => (
                    <tr key={i} className="hover:bg-muted/30">
                      <td className="px-6 py-3 text-muted-foreground">{fmtDate(t.date)}</td>
                      <td className="px-6 py-3 font-medium">{t.description}</td>
                      <td className="px-6 py-3 text-muted-foreground">{t.category ?? "—"}</td>
                      <td className="px-6 py-3 text-muted-foreground">{t.reference ?? "—"}</td>
                      <td
                        className={`px-6 py-3 text-right font-semibold ${
                          t.type === "credit" ? "text-emerald-600" : "text-red-600"
                        }`}
                      >
                        {t.type === "credit" ? "+" : "−"}
                        {money(t.amount, c)}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
