import { useEffect, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { FileDown, Download } from "lucide-react";
import jsPDF from "jspdf";
import autoTable from "jspdf-autotable";
import { ReportSheet } from "./ReportSheet";
import { loadBrandedLogo, drawBrandedHeader, drawBrandedFooter } from "../lib/reportHeader";
import {
  fetchAssociationId, fetchOwnerLedger, fetchUnitsAndOwners, num,
  type UnitInfo, type OwnerInfo,
} from "../lib/ownerLedger";

const TEAL: [number, number, number] = [0, 137, 123];

type Row = { account: string; property: string; ownerName: string; credit: number };

/**
 * Buildium-style "Pre Paid Homeowners": every unit whose owner ledger nets to
 * a credit (payments exceed charges) as of the chosen date, with the credit amount.
 */
export function PrepaidHomeownersReport({ companyId, companyName, logoUrl, to: propTo }: { companyId: string; companyName: string; logoUrl?: string | null; to?: string }) {
  const [asOf, setAsOf] = useState(() => propTo ?? new Date().toISOString().slice(0, 10));
  useEffect(() => { if (propTo) setAsOf(propTo); }, [propTo]);

  const { data, isLoading } = useQuery({
    queryKey: ["prepaid-homeowners", companyId, asOf],
    enabled: !!companyId,
    queryFn: async () => {
      const associationId = await fetchAssociationId(companyId);
      if (!associationId) return null;
      const [entries, { units, owners }] = await Promise.all([
        fetchOwnerLedger(associationId, asOf),
        fetchUnitsAndOwners(associationId),
      ]);
      return { entries, units, owners };
    },
  });

  const { rows, total } = useMemo(() => {
    if (!data) return { rows: [] as Row[], total: 0 };
    const unitById = new Map<string, UnitInfo>();
    for (const u of data.units) unitById.set(u.id, u);
    const ownerById = new Map<string, OwnerInfo>();
    for (const o of data.owners) ownerById.set(o.id, o);
    const ownerByUnit = new Map<string, OwnerInfo>();
    for (const o of data.owners) if (o.unit_id && !ownerByUnit.has(o.unit_id)) ownerByUnit.set(o.unit_id, o);

    const bal = new Map<string, number>();
    for (const e of data.entries) {
      const key = e.unit_id ? `u:${e.unit_id}` : e.owner_id ? `o:${e.owner_id}` : null;
      if (!key) continue;
      bal.set(key, (bal.get(key) ?? 0) + e.debit - e.credit);
    }

    const out: Row[] = [];
    for (const [key, b] of bal) {
      if (b >= -0.004) continue; // only credit balances
      const unitId = key.startsWith("u:") ? key.slice(2) : null;
      const ownerId = key.startsWith("o:") ? key.slice(2) : null;
      const unit = unitId ? unitById.get(unitId) : undefined;
      const owner = (unitId ? ownerByUnit.get(unitId) : null) ?? (ownerId ? ownerById.get(ownerId) : null) ?? null;
      const property = [unit?.address, unit?.unit_number && !unit?.address?.includes(unit.unit_number) ? unit.unit_number : null]
        .filter(Boolean).join(" ") || (unit?.unit_number ? `Unit ${unit.unit_number}` : "—");
      out.push({
        account: unit?.account_number || unit?.unit_number || "—",
        property,
        ownerName: owner ? `${owner.first_name ?? ""} ${owner.last_name ?? ""}`.trim() || "—" : "—",
        credit: -b,
      });
    }
    out.sort((a, b) => b.credit - a.credit);
    return { rows: out, total: out.reduce((s, r) => s + r.credit, 0) };
  }, [data]);

  const asOfLabel = new Date(asOf + "T00:00:00").toLocaleDateString("en-US", { month: "numeric", day: "numeric", year: "numeric" });

  const exportPDF = async () => {
    const doc = new jsPDF({ unit: "pt", format: "letter" });
    const ML = 40;
    const logo = await loadBrandedLogo(logoUrl);
    const startY = drawBrandedHeader(doc, {
      logo, title: "Pre Paid Homeowners", subtitle: `For ${asOfLabel}`,
      metaLines: [{ label: "Properties:", value: companyName || "" }],
    });
    autoTable(doc, {
      startY,
      head: [["Account", "Property", "Owner Name", "Credit Amount"]],
      body: [
        ...rows.map((r) => [r.account, r.property, r.ownerName, num(r.credit)]),
        [
          { content: "", styles: {} } as any,
          { content: "", styles: {} } as any,
          { content: "Total", styles: { fontStyle: "bold", halign: "right" } } as any,
          { content: num(total), styles: { fontStyle: "bold", halign: "right" } } as any,
        ],
      ],
      styles: { fontSize: 8.5, cellPadding: 4 },
      headStyles: { fillColor: TEAL, textColor: 255 },
      columnStyles: { 3: { halign: "right" } },
      margin: { left: ML, right: ML },
    });
    drawBrandedFooter(doc);
    doc.save(`prepaid-homeowners-${asOf}.pdf`);
  };

  const exportCSV = () => {
    const q = (s: string) => `"${s.replace(/"/g, '""')}"`;
    const f = (n: number) => n.toFixed(2);
    const lines = [["Account", "Property", "Owner Name", "Credit Amount"].join(",")];
    for (const r of rows) lines.push([q(r.account), q(r.property), q(r.ownerName), f(r.credit)].join(","));
    lines.push(["", "", "Total", f(total)].join(","));
    const blob = new Blob([lines.join("\n")], { type: "text/csv" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = `prepaid-homeowners-${asOf}.csv`;
    a.click();
    URL.revokeObjectURL(a.href);
  };

  return (
    <div className="space-y-4">
      <Card>
        <CardContent className="flex flex-wrap items-end gap-4 py-4">
          <div>
            <Label className="text-xs text-muted-foreground">As of</Label>
            <div className="mt-1 text-sm font-medium">{asOfLabel}</div>
          </div>
          {rows.length > 0 && (
            <div className="ml-auto flex gap-2">
              <Button variant="outline" onClick={exportCSV}><Download className="mr-1 h-4 w-4" /> CSV</Button>
              <Button onClick={exportPDF}><FileDown className="mr-1 h-4 w-4" /> PDF</Button>
            </div>
          )}
        </CardContent>
      </Card>

      {isLoading ? (
        <Card><CardContent className="p-8 text-center text-sm text-muted-foreground">Loading…</CardContent></Card>
      ) : rows.length === 0 ? (
        <Card><CardContent className="p-8 text-center text-sm text-muted-foreground">No prepaid balances as of {asOfLabel}.</CardContent></Card>
      ) : (
        <ReportSheet title="Pre Paid Homeowners" subtitle={`For ${asOfLabel}`} companyName={companyName} logoUrl={logoUrl}>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-y text-[11px] uppercase tracking-wide text-muted-foreground">
                  <th className="px-3 py-2 text-left font-semibold">Account</th>
                  <th className="px-3 py-2 text-left font-semibold">Property</th>
                  <th className="px-3 py-2 text-left font-semibold">Owner Name</th>
                  <th className="px-3 py-2 text-right font-semibold">Credit Amount</th>
                </tr>
              </thead>
              <tbody>
                {rows.map((r, i) => (
                  <tr key={i} className={`border-b ${i % 2 ? "" : "bg-muted/20"}`}>
                    <td className="px-3 py-1.5 font-mono text-xs">{r.account}</td>
                    <td className="px-3 py-1.5">{r.property}</td>
                    <td className="px-3 py-1.5">{r.ownerName}</td>
                    <td className="px-3 py-1.5 text-right tabular-nums">{num(r.credit)}</td>
                  </tr>
                ))}
              </tbody>
              <tfoot>
                <tr className="border-t-2 border-b-2 font-bold">
                  <td className="px-3 py-2" colSpan={3}>
                    <span className="float-right">Total</span>
                  </td>
                  <td className="px-3 py-2 text-right tabular-nums">{num(total)}</td>
                </tr>
              </tfoot>
            </table>
          </div>
        </ReportSheet>
      )}
    </div>
  );
}
