import { useState, useEffect, useMemo } from "react";
import { useSearchParams } from "react-router-dom";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { Landmark, Plus, Search, Download, CheckCircle2, Circle, Filter } from "lucide-react";
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" },
];

export default function CompanyBankRegisterPage() {
  const { toast } = useToast();
  const [searchParams, setSearchParams] = useSearchParams();
  const [bankAccounts, setBankAccounts] = useState<any[]>([]);
  const [accountId, setAccountId] = useState<string>(searchParams.get("account") || "all");
  const [transactions, setTransactions] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  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: "",
    category: "",
    company_bank_account_id: "",
  });

  const fetchAccounts = async () => {
    const { data } = await supabase
      .from("company_bank_accounts")
      .select("*")
      .eq("status", "active")
      .order("account_name");
    setBankAccounts(data || []);
  };

  const fetchTransactions = async () => {
    setLoading(true);
    let query = supabase
      .from("company_bank_transactions")
      .select("*, company_bank_accounts(account_name)")
      .order("date", { ascending: false })
      .order("created_at", { ascending: false });
    if (accountId !== "all") {
      query = query.eq("company_bank_account_id", accountId);
    }
    const { data, error } = await query;
    if (error) {
      toast({ title: "Error", description: error.message, variant: "destructive" });
    } else {
      setTransactions(data || []);
    }
    setLoading(false);
  };

  useEffect(() => { fetchAccounts(); }, []);
  useEffect(() => { fetchTransactions(); }, [accountId]);

  // Sync URL ?account=
  useEffect(() => {
    if (accountId === "all") {
      searchParams.delete("account");
    } else {
      searchParams.set("account", accountId);
    }
    setSearchParams(searchParams, { replace: true });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [accountId]);

  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) ||
        (t.category || "").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 runningBalance = useMemo(() => {
    const sorted = [...filtered].reverse();
    let bal = 0;
    const balances: Record<string, number> = {};
    sorted.forEach((t) => {
      bal += (Number(t.credit) || 0) - (Number(t.debit) || 0);
      balances[t.id] = bal;
    });
    return balances;
  }, [filtered]);

  const openNew = () => {
    setForm({
      date: new Date().toISOString().split("T")[0],
      transaction_type: "payment",
      description: "",
      reference_number: "",
      debit: "",
      credit: "",
      category: "",
      company_bank_account_id: accountId !== "all" ? accountId : (bankAccounts[0]?.id || ""),
    });
    setDialogOpen(true);
  };

  const handleSave = async () => {
    if (!form.company_bank_account_id) {
      toast({ variant: "destructive", title: "Select a bank account" });
      return;
    }
    const { data: { user } } = await supabase.auth.getUser();
    const { error } = await supabase.from("company_bank_transactions").insert({
      date: form.date,
      transaction_type: form.transaction_type,
      description: form.description || null,
      reference_number: form.reference_number || null,
      debit: parseFloat(form.debit) || 0,
      credit: parseFloat(form.credit) || 0,
      category: form.category || null,
      company_bank_account_id: form.company_bank_account_id,
      created_by: user?.id,
    });
    if (error) {
      toast({ title: "Error", description: error.message, variant: "destructive" });
    } else {
      toast({ title: "Transaction added" });
      setDialogOpen(false);
      fetchTransactions();
    }
  };

  const toggleCleared = async (id: string, current: boolean) => {
    const { error } = await supabase.from("company_bank_transactions").update({
      is_cleared: !current,
      cleared_date: !current ? new Date().toISOString().split("T")[0] : null,
    }).eq("id", id);
    if (!error) fetchTransactions();
  };

  const exportCSV = async () => {
    const rows = [["Date", "Account", "Type", "Description", "Ref#", "Debit", "Credit", "Cleared", "Category"]];
    filtered.forEach((t) => rows.push([
      t.date,
      t.company_bank_accounts?.account_name || "",
      t.transaction_type,
      t.description || "",
      t.reference_number || "",
      Number(t.debit || 0).toFixed(2),
      Number(t.credit || 0).toFixed(2),
      t.is_cleared ? "Yes" : "No",
      t.category || "",
    ]));
    const csv = rows.map((r) => r.map((c) => `"${c}"`).join(",")).join("\n");
    const { saveCsv } = await import("@/lib/saveFile");
    await saveCsv(csv, `company-register-${format(new Date(), "yyyy-MM-dd")}.csv`);
  };

  const totalDebits = filtered.reduce((s, t) => s + (Number(t.debit) || 0), 0);
  const totalCredits = filtered.reduce((s, t) => s + (Number(t.credit) || 0), 0);
  const selectedAccount = bankAccounts.find((b) => b.id === accountId);

  return (
    <div className="space-y-6">
      <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
        <div className="flex items-center gap-2">
          <Landmark className="h-6 w-6 text-primary" />
          <div>
            <h1 className="text-2xl font-bold">Company Bank Register</h1>
            <p className="text-sm text-muted-foreground">Transactions for the management company's own bank accounts.</p>
          </div>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <Button variant="outline" size="sm" onClick={exportCSV}>
            <Download className="h-4 w-4 mr-1" /> Export
          </Button>
          <Button size="sm" onClick={openNew}>
            <Plus className="h-4 w-4 mr-1" /> Add Transaction
          </Button>
        </div>
      </div>

      {/* Account selector */}
      <Card>
        <CardContent className="p-4 grid grid-cols-1 sm:grid-cols-2 gap-4">
          <div>
            <Label>Bank Account</Label>
            <Select value={accountId} onValueChange={setAccountId}>
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Accounts</SelectItem>
                {bankAccounts.map((b) => (
                  <SelectItem key={b.id} value={b.id}>
                    {b.account_name}{b.bank_name ? ` — ${b.bank_name}` : ""}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          {selectedAccount && (
            <div className="flex items-end">
              <div className="text-sm text-muted-foreground">
                Account balance: <span className="font-semibold text-foreground">${Number(selectedAccount.current_balance || 0).toLocaleString("en-US", { minimumFractionDigits: 2 })}</span>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Summary */}
      <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
        <Card><CardContent className="p-4">
          <p className="text-sm text-muted-foreground">Total Debits</p>
          <p className="text-xl font-bold text-destructive">${totalDebits.toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
        </CardContent></Card>
        <Card><CardContent className="p-4">
          <p className="text-sm text-muted-foreground">Total Credits</p>
          <p className="text-xl font-bold text-primary">${totalCredits.toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
        </CardContent></Card>
        <Card><CardContent className="p-4">
          <p className="text-sm text-muted-foreground">Net</p>
          <p className="text-xl font-bold">${(totalCredits - totalDebits).toLocaleString("en-US", { minimumFractionDigits: 2 })}</p>
        </CardContent></Card>
      </div>

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

      {/* Table */}
      <Card>
        <CardContent className="p-0">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-10"></TableHead>
                <TableHead>Date</TableHead>
                {accountId === "all" && <TableHead>Account</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>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow><TableCell colSpan={accountId === "all" ? 9 : 8} className="text-center py-8 text-muted-foreground">Loading...</TableCell></TableRow>
              ) : filtered.length === 0 ? (
                <TableRow><TableCell colSpan={accountId === "all" ? 9 : 8} className="text-center py-8 text-muted-foreground">No transactions found</TableCell></TableRow>
              ) : filtered.map((t) => (
                <TableRow key={t.id} className={t.is_cleared ? "bg-muted/30" : ""}>
                  <TableCell>
                    <button onClick={() => toggleCleared(t.id, t.is_cleared)} className="p-1 hover:bg-muted rounded">
                      {t.is_cleared ? <CheckCircle2 className="h-4 w-4 text-primary" /> : <Circle className="h-4 w-4 text-muted-foreground" />}
                    </button>
                  </TableCell>
                  <TableCell className="whitespace-nowrap">{format(new Date(t.date + "T00:00:00"), "MM/dd/yyyy")}</TableCell>
                  {accountId === "all" && (
                    <TableCell className="text-sm text-muted-foreground">{t.company_bank_accounts?.account_name || "—"}</TableCell>
                  )}
                  <TableCell><Badge variant="outline" className="text-xs">{t.transaction_type}</Badge></TableCell>
                  <TableCell className="max-w-[280px] truncate">{t.description || "—"}</TableCell>
                  <TableCell>{t.reference_number || "—"}</TableCell>
                  <TableCell className="text-right text-destructive">{Number(t.debit) > 0 ? `$${Number(t.debit).toFixed(2)}` : ""}</TableCell>
                  <TableCell className="text-right text-primary">{Number(t.credit) > 0 ? `$${Number(t.credit).toFixed(2)}` : ""}</TableCell>
                  <TableCell className="text-right font-medium">${(runningBalance[t.id] || 0).toFixed(2)}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>Add Company Transaction</DialogTitle></DialogHeader>
          <div className="grid gap-4">
            <div>
              <Label>Bank Account *</Label>
              <Select value={form.company_bank_account_id} onValueChange={(v) => setForm({ ...form, company_bank_account_id: v })}>
                <SelectTrigger><SelectValue placeholder="Select account" /></SelectTrigger>
                <SelectContent>
                  {bankAccounts.map((b) => (
                    <SelectItem key={b.id} value={b.id}>{b.account_name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <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 className="grid grid-cols-2 gap-4">
              <div><Label>Reference #</Label><Input value={form.reference_number} onChange={(e) => setForm({ ...form, reference_number: e.target.value })} /></div>
              <div><Label>Category</Label><Input value={form.category} onChange={(e) => setForm({ ...form, category: e.target.value })} /></div>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Debit ($)</Label><Input type="number" min="0" step="0.01" value={form.debit} onChange={(e) => setForm({ ...form, debit: e.target.value })} /></div>
              <div><Label>Credit ($)</Label><Input type="number" min="0" step="0.01" value={form.credit} onChange={(e) => setForm({ ...form, credit: e.target.value })} /></div>
            </div>
          </div>
          <DialogFooter><Button onClick={handleSave}>Save Transaction</Button></DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
