import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { BookOpen, Plus, Search, Download, DollarSign } from "lucide-react";
import UnitOwnerSelect from "@/components/UnitOwnerSelect";
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 { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { format } from "date-fns";

const txnTypes = [
  "assessment", "special_assessment", "late_fee", "interest", "fine",
  "admin_charge", "payment", "reversal", "credit", "adjustment"
];

const txnTypeLabels: Record<string, string> = {
  assessment: "Assessment", special_assessment: "Special Assessment",
  late_fee: "Late Fee", interest: "Interest", fine: "Fine",
  admin_charge: "Admin Charge", payment: "Payment", reversal: "Reversal",
  credit: "Credit", adjustment: "Adjustment"
};

export default function OwnerLedgerPage() {
  const { toast } = useToast();
  const [entries, setEntries] = useState<any[]>([]);
  const [owners, setOwners] = useState<any[]>([]);
  const [units, setUnits] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [selectedOwnerId, setSelectedOwnerId] = useState("");
  const [search, setSearch] = useState("");
  const [fromLastZero, setFromLastZero] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [form, setForm] = useState({
    date: new Date().toISOString().split("T")[0],
    transaction_type: "assessment",
    description: "",
    debit: "",
    credit: "",
    unit_id: "",
  });

  useEffect(() => {
    Promise.all([
      supabase.from("owners").select("id, first_name, last_name, unit_id, association_id, units(unit_number)").eq("status", "active").order("last_name"),
      supabase.from("units").select("id, unit_number, association_id").order("unit_number"),
    ]).then(([oRes, uRes]) => {
      setOwners(oRes.data || []);
      setUnits(uRes.data || []);
      if (oRes.data?.length) setSelectedOwnerId(oRes.data[0].id);
      setLoading(false);
    });
  }, []);

  useEffect(() => {
    if (selectedOwnerId) fetchLedger();
  }, [selectedOwnerId]);

  const fetchLedger = async () => {
    setLoading(true);
    const { data } = await supabase
      .from("owner_ledger_entries")
      .select("*, units(unit_number)")
      .eq("owner_id", selectedOwnerId)
      .order("date", { ascending: true })
      .order("created_at", { ascending: true });
    setEntries(data || []);
    setLoading(false);
  };

  const filtered = useMemo(() => {
    if (!search) return entries;
    const q = search.toLowerCase();
    return entries.filter(e => (e.description || "").toLowerCase().includes(q) || (e.transaction_type || "").toLowerCase().includes(q));
  }, [entries, search]);

  const withBalance = useMemo(() => {
    let bal = 0;
    const all = filtered.map(e => {
      bal += Number(e.debit) - Number(e.credit);
      return { ...e, runningBalance: bal };
    });
    if (!fromLastZero) return all;
    // Find the index of the LAST entry where running balance reached zero (within 1 cent).
    // Show entries AFTER that point. If balance never returned to zero, show all.
    let lastZeroIdx = -1;
    for (let i = 0; i < all.length; i++) {
      if (Math.abs(all[i].runningBalance) < 0.01) lastZeroIdx = i;
    }
    if (lastZeroIdx < 0) return all;
    // Recompute running balance starting fresh after the zero point
    const sliced = all.slice(lastZeroIdx + 1);
    let b = 0;
    return sliced.map(e => {
      b += Number(e.debit) - Number(e.credit);
      return { ...e, runningBalance: b };
    });
  }, [filtered, fromLastZero]);

  const currentBalance = withBalance.length > 0 ? withBalance[withBalance.length - 1].runningBalance : 0;
  const selectedOwner = owners.find(o => o.id === selectedOwnerId);

  const handleCreate = async () => {
    if (!selectedOwnerId) return;
    const owner = owners.find(o => o.id === selectedOwnerId);
    await supabase.from("owner_ledger_entries").insert({
      owner_id: selectedOwnerId,
      association_id: owner?.association_id,
      unit_id: form.unit_id || owner?.unit_id || null,
      date: form.date,
      transaction_type: form.transaction_type,
      description: form.description,
      debit: parseFloat(form.debit) || 0,
      credit: parseFloat(form.credit) || 0,
    });

    toast({ title: "Ledger entry added" });
    setDialogOpen(false);
    fetchLedger();

    // Update owner balance
    const newBal = currentBalance + (parseFloat(form.debit) || 0) - (parseFloat(form.credit) || 0);
    await supabase.from("owners").update({ balance: newBal }).eq("id", selectedOwnerId);
  };

  const exportCSV = async () => {
    const rows = [
      ["Date", "Type", "Description", "Debit", "Credit", "Balance"].join(","),
      ...withBalance.map(e => [e.date, txnTypeLabels[e.transaction_type] || e.transaction_type, `"${(e.description || "").replace(/"/g, '""')}"`, Number(e.debit).toFixed(2), Number(e.credit).toFixed(2), e.runningBalance.toFixed(2)].join(","))
    ].join("\n");
    const { saveCsv } = await import("@/lib/saveFile");
    await saveCsv(rows, `Owner_Ledger_${selectedOwner ? `${selectedOwner.last_name}_${selectedOwner.first_name}` : "export"}_${format(new Date(), "yyyy-MM-dd")}.csv`);
  };

  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"><BookOpen className="h-6 w-6 text-primary" /> Owner Ledger</h1>
          <p className="text-sm text-muted-foreground mt-1">View and manage owner account balances and transactions.</p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" className="gap-2" onClick={exportCSV}><Download className="h-4 w-4" /> Export</Button>
          <Button className="gap-2" onClick={() => {
            setForm({ date: new Date().toISOString().split("T")[0], transaction_type: "assessment", description: "", debit: "", credit: "", unit_id: selectedOwner?.unit_id || "" });
            setDialogOpen(true);
          }}><Plus className="h-4 w-4" /> Post Entry</Button>
        </div>
      </div>

      {/* Owner selector and balance */}
      <div className="grid gap-4 md:grid-cols-3">
        <Card>
          <CardContent className="pt-6 space-y-3">
            <Label className="text-xs font-semibold text-muted-foreground uppercase">Select Owner</Label>
            <UnitOwnerSelect
              owners={owners}
              value={selectedOwnerId}
              onValueChange={setSelectedOwnerId}
              placeholder="Select owner"
            />
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-6">
            <p className="text-xs text-muted-foreground uppercase font-semibold">Current Balance</p>
            <p className={`text-3xl font-bold font-mono ${currentBalance > 0 ? "text-destructive" : currentBalance < 0 ? "text-emerald-600" : ""}`}>
              ${Math.abs(currentBalance).toLocaleString("en-US", { minimumFractionDigits: 2 })}
              {currentBalance < 0 ? " CR" : currentBalance > 0 ? " DUE" : ""}
            </p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-6">
            <p className="text-xs text-muted-foreground uppercase font-semibold">Transactions</p>
            <p className="text-3xl font-bold">{entries.length}</p>
          </CardContent>
        </Card>
      </div>

      <div className="flex flex-wrap items-center gap-3">
        <div className="relative max-w-md flex-1 min-w-[220px]">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input placeholder="Search ledger..." className="pl-10" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        <Button
          variant={fromLastZero ? "default" : "outline"}
          size="sm"
          onClick={() => setFromLastZero(v => !v)}
          title="Show only entries since the most recent $0.00 balance"
        >
          {fromLastZero ? "Showing from last $0 balance" : "From last $0 balance"}
        </Button>
      </div>

      {loading ? (
        <div className="flex justify-center py-12"><div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" /></div>
      ) : !selectedOwnerId ? (
        <Card><CardContent className="py-12 text-center text-muted-foreground">Select an owner to view their ledger.</CardContent></Card>
      ) : withBalance.length === 0 ? (
        <Card><CardContent className="py-12 text-center text-muted-foreground">No ledger entries for this owner.</CardContent></Card>
      ) : (
        <Card>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Date</TableHead>
                <TableHead>Type</TableHead>
                <TableHead>Description</TableHead>
                <TableHead>Unit</TableHead>
                <TableHead className="text-right">Charge</TableHead>
                <TableHead className="text-right">Payment</TableHead>
                <TableHead className="text-right">Balance</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {withBalance.map((e) => (
                <TableRow key={e.id}>
                  <TableCell className="font-medium whitespace-nowrap">{format(new Date(e.date + "T00:00:00"), "MM/dd/yyyy")}</TableCell>
                  <TableCell>
                    <Badge variant="outline" className="text-xs capitalize">{txnTypeLabels[e.transaction_type] || e.transaction_type}</Badge>
                  </TableCell>
                  <TableCell>{e.description || "—"}</TableCell>
                  <TableCell>{e.units?.unit_number || "—"}</TableCell>
                  <TableCell className="text-right font-mono">
                    {Number(e.debit) > 0 ? <span className="text-destructive">${Number(e.debit).toLocaleString("en-US", { minimumFractionDigits: 2 })}</span> : "—"}
                  </TableCell>
                  <TableCell className="text-right font-mono">
                    {Number(e.credit) > 0 ? <span className="text-emerald-600">${Number(e.credit).toLocaleString("en-US", { minimumFractionDigits: 2 })}</span> : "—"}
                  </TableCell>
                  <TableCell className={`text-right font-mono font-bold ${e.runningBalance > 0 ? "text-destructive" : e.runningBalance < 0 ? "text-emerald-600" : ""}`}>
                    ${Math.abs(e.runningBalance).toLocaleString("en-US", { minimumFractionDigits: 2 })}
                    {e.runningBalance < 0 ? " CR" : ""}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </Card>
      )}

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>Post Ledger Entry</DialogTitle></DialogHeader>
          <div className="space-y-4">
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Date</Label><Input type="date" value={form.date} onChange={(e) => setForm({ ...form, date: e.target.value })} /></div>
              <div>
                <Label>Transaction Type</Label>
                <Select value={form.transaction_type} onValueChange={(v) => setForm({ ...form, transaction_type: v })}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>{txnTypes.map(t => <SelectItem key={t} value={t}>{txnTypeLabels[t]}</SelectItem>)}</SelectContent>
                </Select>
              </div>
            </div>
            <div><Label>Description</Label><Input value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} /></div>
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Charge (Debit)</Label><Input type="number" value={form.debit} onChange={(e) => setForm({ ...form, debit: e.target.value })} placeholder="0.00" /></div>
              <div><Label>Payment (Credit)</Label><Input type="number" value={form.credit} onChange={(e) => setForm({ ...form, credit: e.target.value })} placeholder="0.00" /></div>
            </div>
          </div>
          <DialogFooter><Button onClick={handleCreate}>Post Entry</Button></DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
