import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { useSearchParams } from "react-router-dom";
import { Landmark, Plus, Search, Download, CheckCircle2, Circle, Filter, Trash2 } from "lucide-react";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
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 = [
  { value: "deposit", label: "Deposit" },
  { value: "payment", label: "Payment" },
  { value: "check", label: "Check" },
  { value: "transfer_in", label: "Transfer In" },
  { value: "transfer_out", label: "Transfer Out" },
  { value: "adjustment", label: "Adjustment" },
  { value: "fee", label: "Fee" },
  { value: "owner_payment", label: "Owner Payment" },
  { value: "vendor_payment", label: "Vendor Payment" },
];

export default function BankRegisterPage() {
  const { toast } = useToast();
  const [searchParams] = useSearchParams();
  const preselectedAccount = searchParams.get("account");

  const [transactions, setTransactions] = useState<any[]>([]);
  const [bankAccounts, setBankAccounts] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [selectedAccountId, setSelectedAccountId] = useState(preselectedAccount || "");
  const [clearedFilter, setClearedFilter] = useState<"all" | "cleared" | "uncleared">("all");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [form, setForm] = useState({
    date: new Date().toISOString().split("T")[0],
    transaction_type: "payment",
    description: "",
    reference_number: "",
    debit: "",
    credit: "",
  });

  useEffect(() => {
    supabase.from("bank_accounts").select("id, account_name, bank_name, association_id, associations(name)").eq("status", "active").order("account_name")
      .then(({ data }) => {
        setBankAccounts(data || []);
        if (!selectedAccountId && data?.length) setSelectedAccountId(data[0].id);
      });
  }, []);

  useEffect(() => {
    if (selectedAccountId) fetchTransactions();
  }, [selectedAccountId]);

  const fetchTransactions = async () => {
    setLoading(true);
    const { data } = await supabase
      .from("bank_transactions")
      .select("*")
      .eq("bank_account_id", selectedAccountId)
      .order("date", { ascending: true })
      .order("created_at", { ascending: true });
    setTransactions(data || []);
    setLoading(false);
  };

  const filtered = useMemo(() => {
    let result = [...transactions];
    if (search) {
      const q = search.toLowerCase();
      result = result.filter(t => (t.description || "").toLowerCase().includes(q) || (t.reference_number || "").toLowerCase().includes(q));
    }
    if (clearedFilter === "cleared") result = result.filter(t => t.is_cleared);
    if (clearedFilter === "uncleared") result = result.filter(t => !t.is_cleared);
    return result;
  }, [transactions, search, clearedFilter]);

  const withBalance = useMemo(() => {
    let bal = 0;
    return filtered.map(t => {
      bal += Number(t.debit) - Number(t.credit);
      return { ...t, runningBalance: bal };
    });
  }, [filtered]);

  const currentBalance = withBalance.length > 0 ? withBalance[withBalance.length - 1].runningBalance : 0;
  const clearedBalance = transactions.filter(t => t.is_cleared).reduce((s, t) => s + Number(t.debit) - Number(t.credit), 0);
  const unclearedBalance = currentBalance - clearedBalance;

  const handleCreate = async () => {
    if (!selectedAccountId) return;
    const acct = bankAccounts.find(a => a.id === selectedAccountId);
    await supabase.from("bank_transactions").insert({
      bank_account_id: selectedAccountId,
      association_id: acct?.association_id,
      date: form.date,
      transaction_type: form.transaction_type,
      description: form.description,
      reference_number: form.reference_number || null,
      debit: parseFloat(form.debit) || 0,
      credit: parseFloat(form.credit) || 0,
    });
    toast({ title: "Transaction added" });
    setDialogOpen(false);
    fetchTransactions();
  };

  const toggleCleared = async (txn: any) => {
    await supabase.from("bank_transactions").update({
      is_cleared: !txn.is_cleared,
      cleared_date: !txn.is_cleared ? new Date().toISOString().split("T")[0] : null,
    }).eq("id", txn.id);
    fetchTransactions();
  };

  const deleteTransaction = async (txn: any) => {
    const { error } = await supabase.from("bank_transactions").delete().eq("id", txn.id);
    if (error) {
      toast({ variant: "destructive", title: "Failed to delete", description: error.message });
      return;
    }
    toast({ title: "Transaction deleted" });
    fetchTransactions();
  };

  const exportCSV = async () => {
    const rows = [
      ["Date", "Type", "Description", "Ref #", "Debit", "Credit", "Balance", "Cleared"].join(","),
      ...withBalance.map(t => [
        t.date, t.transaction_type, `"${(t.description || "").replace(/"/g, '""')}"`,
        t.reference_number || "", Number(t.debit).toFixed(2), Number(t.credit).toFixed(2),
        t.runningBalance.toFixed(2), t.is_cleared ? "Yes" : "No"
      ].join(","))
    ].join("\n");
    const { saveCsv } = await import("@/lib/saveFile");
    await saveCsv(rows, `Bank_Register_${format(new Date(), "yyyy-MM-dd")}.csv`);
  };

  const selectedAccount = bankAccounts.find(a => a.id === selectedAccountId);

  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">
            <Landmark className="h-6 w-6 text-primary" /> Bank Register
          </h1>
          <p className="text-sm text-muted-foreground mt-1">
            {selectedAccount ? `${selectedAccount.account_name} — ${selectedAccount.associations?.name || ""}` : "Select an account"}
          </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: "payment", description: "", reference_number: "", debit: "", credit: "" });
            setDialogOpen(true);
          }}><Plus className="h-4 w-4" /> New Transaction</Button>
        </div>
      </div>

      {/* Account selector and summary */}
      <div className="grid gap-4 md:grid-cols-4">
        <Card className="md:col-span-1">
          <CardContent className="pt-6 space-y-3">
            <Label className="text-xs font-semibold text-muted-foreground uppercase">Bank Account</Label>
            <Select value={selectedAccountId} onValueChange={setSelectedAccountId}>
              <SelectTrigger><SelectValue placeholder="Select account" /></SelectTrigger>
              <SelectContent>
                {bankAccounts.map(a => (
                  <SelectItem key={a.id} value={a.id}>{a.account_name}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-6">
            <p className="text-xs text-muted-foreground uppercase font-semibold">Register Balance</p>
            <p className="text-2xl font-bold font-mono">${currentBalance.toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-6">
            <p className="text-xs text-muted-foreground uppercase font-semibold">Cleared Balance</p>
            <p className="text-2xl font-bold font-mono text-emerald-600">${clearedBalance.toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-6">
            <p className="text-xs text-muted-foreground uppercase font-semibold">Uncleared</p>
            <p className="text-2xl font-bold font-mono text-amber-600">${unclearedBalance.toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
          </CardContent>
        </Card>
      </div>

      {/* Filters */}
      <div className="flex gap-2 flex-wrap">
        <div className="relative flex-1 max-w-md">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input placeholder="Search transactions..." className="pl-10" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        <Select value={clearedFilter} onValueChange={(v: any) => setClearedFilter(v)}>
          <SelectTrigger className="w-40"><Filter className="h-4 w-4 mr-2" /><SelectValue /></SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All</SelectItem>
            <SelectItem value="cleared">Cleared</SelectItem>
            <SelectItem value="uncleared">Uncleared</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Register Table */}
      {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>
      ) : !selectedAccountId ? (
        <Card><CardContent className="py-12 text-center text-muted-foreground">Select a bank account to view its register.</CardContent></Card>
      ) : withBalance.length === 0 ? (
        <Card><CardContent className="py-12 text-center text-muted-foreground">No transactions in this register.</CardContent></Card>
      ) : (
        <Card>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-10">✓</TableHead>
                <TableHead>Date</TableHead>
                <TableHead>Type</TableHead>
                <TableHead>Description</TableHead>
                <TableHead>Ref #</TableHead>
                <TableHead className="text-right">Debit</TableHead>
                <TableHead className="text-right">Credit</TableHead>
                <TableHead className="text-right">Balance</TableHead>
                <TableHead className="w-12"></TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {withBalance.map((t) => (
                <TableRow key={t.id} className={t.is_cleared ? "bg-muted/30" : ""}>
                  <TableCell>
                    <button onClick={() => toggleCleared(t)} className="hover:opacity-70">
                      {t.is_cleared
                        ? <CheckCircle2 className="h-4 w-4 text-emerald-600" />
                        : <Circle className="h-4 w-4 text-muted-foreground" />}
                    </button>
                  </TableCell>
                  <TableCell className="font-medium whitespace-nowrap">{format(new Date(t.date + "T00:00:00"), "MM/dd/yyyy")}</TableCell>
                  <TableCell>
                    <Badge variant="outline" className="capitalize text-xs">{t.transaction_type.replace("_", " ")}</Badge>
                  </TableCell>
                  <TableCell>{t.description || "—"}</TableCell>
                  <TableCell className="text-muted-foreground">{t.reference_number || "—"}</TableCell>
                  <TableCell className="text-right font-mono">
                    {Number(t.debit) > 0 ? <span className="text-emerald-600">${Number(t.debit).toLocaleString("en-US", { minimumFractionDigits: 2 })}</span> : "—"}
                  </TableCell>
                  <TableCell className="text-right font-mono">
                    {Number(t.credit) > 0 ? <span className="text-destructive">${Number(t.credit).toLocaleString("en-US", { minimumFractionDigits: 2 })}</span> : "—"}
                  </TableCell>
                  <TableCell className={`text-right font-mono font-bold ${t.runningBalance < 0 ? "text-destructive" : ""}`}>
                    ${t.runningBalance.toLocaleString("en-US", { minimumFractionDigits: 2 })}
                  </TableCell>
                  <TableCell>
                    <AlertDialog>
                      <AlertDialogTrigger asChild>
                        <Button variant="ghost" size="icon" className="h-7 w-7 text-muted-foreground hover:text-destructive">
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </AlertDialogTrigger>
                      <AlertDialogContent>
                        <AlertDialogHeader>
                          <AlertDialogTitle>Delete transaction?</AlertDialogTitle>
                          <AlertDialogDescription>
                            This will permanently remove this bank transaction from the register. If it was linked to a check or payment, the source record will not be affected.
                          </AlertDialogDescription>
                        </AlertDialogHeader>
                        <AlertDialogFooter>
                          <AlertDialogCancel>Cancel</AlertDialogCancel>
                          <AlertDialogAction onClick={() => deleteTransaction(t)} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
                            Delete
                          </AlertDialogAction>
                        </AlertDialogFooter>
                      </AlertDialogContent>
                    </AlertDialog>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </Card>
      )}

      {/* New Transaction Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>New Transaction</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>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} value={t.value}>{t.label}</SelectItem>)}
                  </SelectContent>
                </Select>
              </div>
            </div>
            <div><Label>Description</Label><Input value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} /></div>
            <div><Label>Reference / Check #</Label><Input value={form.reference_number} onChange={(e) => setForm({ ...form, reference_number: e.target.value })} /></div>
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Debit (Money In)</Label><Input type="number" value={form.debit} onChange={(e) => setForm({ ...form, debit: e.target.value })} placeholder="0.00" /></div>
              <div><Label>Credit (Money Out)</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}>Add Transaction</Button></DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
