import { useState, useEffect } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { FileSearch, Plus, Search, Edit, Trash2, MoreHorizontal, RefreshCw, Repeat } from "lucide-react";
import RecordImportButton from "@/components/RecordImportButton";
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 { Checkbox } from "@/components/ui/checkbox";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";

const statusColors: Record<string, string> = { pending: "bg-amber-100 text-amber-700", approved: "bg-blue-100 text-blue-700", paid: "bg-emerald-100 text-emerald-700", overdue: "bg-red-100 text-red-700" };

const FREQUENCY_OPTIONS = [
  { value: "none", label: "Not recurring" },
  { value: "weekly", label: "Weekly" },
  { value: "biweekly", label: "Bi-weekly" },
  { value: "monthly", label: "Monthly" },
  { value: "quarterly", label: "Quarterly" },
  { value: "semiannual", label: "Semi-annual" },
  { value: "annual", label: "Annual" },
];

export default function InvoiceTrackingPage() {
  const { toast } = useToast();
  const [invoices, setInvoices] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [confirmBulkDelete, setConfirmBulkDelete] = useState(false);
  const [bulkDeleting, setBulkDeleting] = useState(false);
  const [generating, setGenerating] = useState(false);
  const [form, setForm] = useState({
    vendor_name: "", invoice_number: "", amount: "", status: "pending",
    due_date: "", description: "", category: "",
    recurrence_frequency: "none", next_generation_date: "", recurrence_end_date: "",
  });

  const syncInvoiceBillRecord = async (invoice: any) => {
    const billPayload = {
      association_id: invoice.association_id,
      description: invoice.description || `Bill from ${invoice.vendor_name}`,
      amount: Number(invoice.amount) || 0,
      bill_date: invoice.issue_date || new Date().toISOString().split("T")[0],
      due_date: invoice.due_date || null,
      invoice_number: invoice.invoice_number || null,
      expense_account_id: null,
      status: invoice.status === "paid" ? "paid" : "pending",
      notes: invoice.vendor_name,
      source_invoice_id: invoice.id,
    };
    const { data: existingBill } = await supabase.from("bills").select("id, zoho_bill_id").eq("source_invoice_id", invoice.id).maybeSingle();
    if (existingBill?.id) {
      const { error } = await supabase.from("bills").update(billPayload).eq("id", existingBill.id);
      if (error) throw error;
      return existingBill.id;
    }
    const { data: userData } = await supabase.auth.getUser();
    const { data: newBill, error } = await supabase.from("bills").insert({ ...billPayload, created_by: userData?.user?.id || null }).select("id").single();
    if (error) throw error;
    return newBill?.id || null;
  };

  const fetch = async () => {
    setLoading(true);
    const { data, error } = await supabase.from("invoices").select("*, associations(name)").order("created_at", { ascending: false });
    if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
    else setInvoices(data || []);
    setLoading(false);
  };
  useEffect(() => { fetch(); }, []);

  const openNew = () => {
    setEditing(null);
    setForm({ vendor_name: "", invoice_number: "", amount: "", status: "pending", due_date: "", description: "", category: "", recurrence_frequency: "none", next_generation_date: "", recurrence_end_date: "" });
    setDialogOpen(true);
  };
  const openEdit = (i: any) => {
    setEditing(i);
    setForm({
      vendor_name: i.vendor_name, invoice_number: i.invoice_number || "", amount: i.amount?.toString() || "",
      status: i.status, due_date: i.due_date || "", description: i.description || "", category: i.category || "",
      recurrence_frequency: i.recurrence_frequency || "none",
      next_generation_date: i.next_generation_date || "",
      recurrence_end_date: i.recurrence_end_date || "",
    });
    setDialogOpen(true);
  };

  const handleSave = async () => {
    const isRecurring = form.recurrence_frequency && form.recurrence_frequency !== "none";
    const payload: any = {
      vendor_name: form.vendor_name,
      invoice_number: form.invoice_number,
      amount: parseFloat(form.amount) || 0,
      status: form.status,
      due_date: form.due_date || null,
      description: form.description,
      category: form.category,
      recurrence_frequency: isRecurring ? form.recurrence_frequency : null,
      next_generation_date: isRecurring ? (form.next_generation_date || null) : null,
      recurrence_end_date: isRecurring ? (form.recurrence_end_date || null) : null,
    };
    if (editing) {
      const { data: updatedInvoice, error } = await supabase.from("invoices").update(payload).eq("id", editing.id).select().single();
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      await syncInvoiceBillRecord(updatedInvoice);
      toast({ title: "Invoice updated" });
    } else {
      const { data: assocs } = await supabase.from("associations").select("id").eq("status", "active").limit(1);
      if (!assocs?.length) { toast({ title: "Error", description: "Create an association first", variant: "destructive" }); return; }
      const { data: userData } = await supabase.auth.getUser();
      const { data: newInvoice, error } = await supabase.from("invoices").insert({ ...payload, association_id: assocs[0].id, created_by: userData?.user?.id || null }).select().single();
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      await syncInvoiceBillRecord(newInvoice);
      toast({ title: "Invoice created" });
    }
    setDialogOpen(false); fetch();
  };

  const handleDelete = async (id: string) => {
    const { data: existingBill } = await supabase.from("bills").select("id").eq("source_invoice_id", id).maybeSingle();
    if (existingBill?.id) {
      await supabase.from("bill_approvals").delete().eq("bill_id", existingBill.id);
      await supabase.from("bills").delete().eq("id", existingBill.id);
    }
    await supabase.from("invoices").delete().eq("id", id);
    toast({ title: "Invoice deleted" }); fetch();
  };

  const performBulkDelete = async () => {
    setBulkDeleting(true);
    const ids = Array.from(selectedIds);
    try {
      const { data: bills } = await supabase.from("bills").select("id").in("source_invoice_id", ids);
      const billIds = (bills || []).map((b: any) => b.id);
      if (billIds.length) {
        await supabase.from("bill_approvals").delete().in("bill_id", billIds);
        await supabase.from("bills").delete().in("id", billIds);
      }
      const { error } = await supabase.from("invoices").delete().in("id", ids);
      if (error) throw error;
      toast({ title: `Deleted ${ids.length} invoice(s)` });
      setSelectedIds(new Set());
      setConfirmBulkDelete(false);
      fetch();
    } catch (e: any) {
      toast({ title: "Bulk delete failed", description: e.message, variant: "destructive" });
    } finally {
      setBulkDeleting(false);
    }
  };

  const handleGenerateRecurring = async () => {
    setGenerating(true);
    try {
      const { data, error } = await supabase.functions.invoke("generate-recurring-invoices");
      if (error) throw error;
      toast({ title: "Recurring invoices generated", description: `Created ${data?.created || 0} invoice(s).` });
      fetch();
    } catch (e: any) {
      toast({ title: "Generation failed", description: e.message, variant: "destructive" });
    } finally {
      setGenerating(false);
    }
  };

  const filtered = invoices.filter((i) => i.vendor_name.toLowerCase().includes(search.toLowerCase()) || (i.invoice_number || "").toLowerCase().includes(search.toLowerCase()));
  const allSelected = filtered.length > 0 && filtered.every((i) => selectedIds.has(i.id));
  const toggleAll = () => {
    if (allSelected) setSelectedIds(new Set());
    else setSelectedIds(new Set(filtered.map((i) => i.id)));
  };
  const toggleOne = (id: string) => {
    const next = new Set(selectedIds);
    next.has(id) ? next.delete(id) : next.add(id);
    setSelectedIds(next);
  };

  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"><FileSearch className="h-6 w-6 text-primary" /> Invoice Tracking</h1>
          <p className="text-sm text-muted-foreground mt-1">Track vendor invoices, payment status, and due dates.</p>
        </div>
        <div className="flex gap-2 flex-wrap">
          <Button variant="outline" className="gap-2" onClick={handleGenerateRecurring} disabled={generating}>
            <RefreshCw className={`h-4 w-4 ${generating ? "animate-spin" : ""}`} /> Generate Recurring
          </Button>
          <RecordImportButton
            title="Import Invoices"
            description="Upload a CSV or Excel file with invoice records."
            expectedColumns={[
              { key: "vendor_name", label: "Vendor Name", required: true },
              { key: "invoice_number", label: "Invoice Number" },
              { key: "amount", label: "Amount", required: true },
              { key: "status", label: "Status" },
              { key: "due_date", label: "Due Date" },
              { key: "description", label: "Description" },
            ]}
            onImport={async (rows) => {
              const { data: a } = await supabase.from("associations").select("id").eq("status", "active").limit(1);
              if (!a?.length) throw new Error("Create an association first");
              const { data: userData } = await supabase.auth.getUser();
              const payload = rows.map(r => ({
                vendor_name: r.vendor_name || "Unknown",
                invoice_number: r.invoice_number || null,
                amount: parseFloat(r.amount) || 0,
                status: r.status || "pending",
                due_date: r.due_date || null,
                description: r.description || null,
                category: r.category || null,
                association_id: a[0].id,
                created_by: userData?.user?.id || null,
              }));
              const { data: insertedInvoices, error } = await supabase.from("invoices").insert(payload).select();
              if (error) throw error;
              for (const invoice of insertedInvoices || []) {
                await syncInvoiceBillRecord(invoice);
              }
              toast({ title: `Imported ${rows.length} invoices` });
              fetch();
            }}
            templateFileName="invoices_template.xlsx"
          />
          <Button className="gap-2" onClick={openNew}><Plus className="h-4 w-4" /> New Invoice</Button>
        </div>
      </div>
      <div className="relative 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 invoices..." className="pl-10" value={search} onChange={(e) => setSearch(e.target.value)} /></div>

      {selectedIds.size > 0 && (
        <div className="flex items-center gap-3 rounded-lg border bg-muted/30 px-3 py-2">
          <span className="text-sm font-medium">{selectedIds.size} selected</span>
          <Button size="sm" variant="destructive" onClick={() => setConfirmBulkDelete(true)}>
            <Trash2 className="h-4 w-4 mr-2" /> Delete Selected
          </Button>
          <Button size="sm" variant="ghost" onClick={() => setSelectedIds(new Set())}>Clear</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> : filtered.length === 0 ? <Card><CardContent className="py-12 text-center text-muted-foreground">No invoices found.</CardContent></Card> : (
        <Card><Table><TableHeader><TableRow>
          <TableHead className="w-10"><Checkbox checked={allSelected} onCheckedChange={toggleAll} /></TableHead>
          <TableHead>Vendor</TableHead><TableHead>Invoice #</TableHead><TableHead>Amount</TableHead><TableHead>Status</TableHead><TableHead>Due Date</TableHead><TableHead>Recurring</TableHead><TableHead className="w-12" /></TableRow></TableHeader><TableBody>
          {filtered.map((i) => (<TableRow key={i.id} data-state={selectedIds.has(i.id) ? "selected" : undefined}>
            <TableCell><Checkbox checked={selectedIds.has(i.id)} onCheckedChange={() => toggleOne(i.id)} /></TableCell>
            <TableCell className="font-medium">{i.vendor_name}</TableCell>
            <TableCell>{i.invoice_number || "—"}</TableCell>
            <TableCell>${Number(i.amount).toLocaleString()}</TableCell>
            <TableCell><Badge className={statusColors[i.status] || "bg-muted text-muted-foreground"}>{i.status}</Badge></TableCell>
            <TableCell>{i.due_date || "—"}</TableCell>
            <TableCell>
              {i.recurrence_frequency ? (
                <Badge variant="outline" className="gap-1"><Repeat className="h-3 w-3" />{i.recurrence_frequency}{i.next_generation_date ? ` · next ${i.next_generation_date}` : ""}</Badge>
              ) : "—"}
            </TableCell>
            <TableCell>
              <DropdownMenu><DropdownMenuTrigger asChild><Button variant="ghost" size="icon" className="h-8 w-8"><MoreHorizontal className="h-4 w-4" /></Button></DropdownMenuTrigger><DropdownMenuContent align="end"><DropdownMenuItem onClick={() => openEdit(i)}><Edit className="h-4 w-4 mr-2" /> Edit</DropdownMenuItem><DropdownMenuItem className="text-destructive" onClick={() => handleDelete(i.id)}><Trash2 className="h-4 w-4 mr-2" /> Delete</DropdownMenuItem></DropdownMenuContent></DropdownMenu>
            </TableCell>
          </TableRow>))}
        </TableBody></Table></Card>
      )}

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}><DialogContent className="max-w-2xl"><DialogHeader><DialogTitle>{editing ? "Edit Invoice" : "New Invoice"}</DialogTitle><DialogDescription>Vendor invoice details, schedule, and recurrence.</DialogDescription></DialogHeader>
        <div className="space-y-4">
          <div className="grid grid-cols-2 gap-4"><div><Label>Vendor</Label><Input value={form.vendor_name} onChange={(e) => setForm({ ...form, vendor_name: e.target.value })} /></div><div><Label>Invoice #</Label><Input value={form.invoice_number} onChange={(e) => setForm({ ...form, invoice_number: e.target.value })} /></div></div>
          <div className="grid grid-cols-2 gap-4"><div><Label>Amount</Label><Input type="number" value={form.amount} onChange={(e) => setForm({ ...form, amount: e.target.value })} /></div>
            <div><Label>Status</Label><Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="pending">Pending</SelectItem><SelectItem value="approved">Approved</SelectItem><SelectItem value="paid">Paid</SelectItem><SelectItem value="overdue">Overdue</SelectItem></SelectContent></Select></div></div>
          <div><Label>Due Date</Label><Input type="date" value={form.due_date} onChange={(e) => setForm({ ...form, due_date: e.target.value })} /></div>
          <div><Label>Description</Label><Textarea value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} /></div>

          <div className="border-t pt-4 space-y-3">
            <div className="flex items-center gap-2"><Repeat className="h-4 w-4 text-primary" /><h3 className="text-sm font-semibold">Recurrence</h3></div>
            <div className="grid grid-cols-3 gap-4">
              <div>
                <Label>Frequency</Label>
                <Select value={form.recurrence_frequency} onValueChange={(v) => setForm({ ...form, recurrence_frequency: v })}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>{FREQUENCY_OPTIONS.map(o => <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div>
                <Label>Next Generation</Label>
                <Input type="date" value={form.next_generation_date} disabled={form.recurrence_frequency === "none"} onChange={(e) => setForm({ ...form, next_generation_date: e.target.value })} />
              </div>
              <div>
                <Label>End Date (optional)</Label>
                <Input type="date" value={form.recurrence_end_date} disabled={form.recurrence_frequency === "none"} onChange={(e) => setForm({ ...form, recurrence_end_date: e.target.value })} />
              </div>
            </div>
            {form.recurrence_frequency !== "none" && (
              <p className="text-xs text-muted-foreground">A new invoice will be generated automatically on the "Next Generation" date and on each subsequent {form.recurrence_frequency} interval.</p>
            )}
          </div>
        </div>
        <DialogFooter><Button onClick={handleSave}>{editing ? "Update" : "Create"}</Button></DialogFooter>
      </DialogContent></Dialog>

      <AlertDialog open={confirmBulkDelete} onOpenChange={setConfirmBulkDelete}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete {selectedIds.size} invoice(s)?</AlertDialogTitle>
            <AlertDialogDescription>
              This will permanently delete the selected invoices and any linked bill records. This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={bulkDeleting}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={performBulkDelete} disabled={bulkDeleting} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
              {bulkDeleting ? "Deleting…" : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
