import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { DollarSign, Plus, Search, MoreHorizontal, Edit, Trash2, ChevronLeft, ChevronRight, CheckCircle2, Upload } from "lucide-react";
import RecordImportButton from "@/components/RecordImportButton";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/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";
import { format, addMonths, subMonths, startOfMonth, parseISO } from "date-fns";

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",
};

export default function PayablesPage() {
  const { toast } = useToast();
  const [payables, setPayables] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [currentMonth, setCurrentMonth] = useState(startOfMonth(new Date()));
  const [associations, setAssociations] = useState<any[]>([]);
  const [form, setForm] = useState({
    vendor_name: "", amount: "", due_date: "", status: "pending",
    description: "", association_id: "",
  });

  const monthStr = format(currentMonth, "yyyy-MM-dd");

  const fetchData = async () => {
    setLoading(true);
    const [{ data }, { data: assocs }] = await Promise.all([
      supabase
        .from("payables")
        .select("*, associations(name)")
        .eq("target_month", monthStr)
        .order("due_date", { ascending: true }),
      supabase.from("associations").select("id, name").eq("status", "active").order("name"),
    ]);
    setPayables(data || []);
    setAssociations(assocs || []);
    setLoading(false);
  };

  useEffect(() => { fetchData(); }, [monthStr]);

  const openNew = () => {
    setEditing(null);
    setForm({
      vendor_name: "", amount: "", due_date: "", status: "pending",
      description: "", association_id: associations[0]?.id || "",
    });
    setDialogOpen(true);
  };

  const openEdit = (p: any) => {
    setEditing(p);
    setForm({
      vendor_name: p.vendor_name, amount: p.amount?.toString() || "",
      due_date: p.due_date || "", status: p.status,
      description: p.description || "",
      association_id: p.association_id || "",
    });
    setDialogOpen(true);
  };

  const handleSave = async () => {
    if (!form.vendor_name) { toast({ variant: "destructive", title: "Vendor name required" }); return; }
    const payload: any = {
      vendor_name: form.vendor_name,
      amount: parseFloat(form.amount) || 0,
      due_date: form.due_date || null,
      status: form.status,
      description: form.description || null,
      target_month: form.due_date
        ? format(startOfMonth(parseISO(form.due_date)), "yyyy-MM-dd")
        : monthStr,
    };

    if (editing) {
      await supabase.from("payables").update(payload).eq("id", editing.id);
      toast({ title: "Payable updated" });
    } else {
      payload.association_id = form.association_id || associations[0]?.id;
      if (!payload.association_id) { toast({ variant: "destructive", title: "No association available" }); return; }
      await supabase.from("payables").insert(payload);
      toast({ title: "Payable created" });
    }
    setDialogOpen(false);
    fetchData();
  };

  const handleDelete = async (id: string) => {
    await supabase.from("payables").delete().eq("id", id);
    toast({ title: "Deleted" });
    fetchData();
  };

  // Check off → move to next month
  const handleCheckOff = async (p: any) => {
    const nextMonth = format(addMonths(currentMonth, 1), "yyyy-MM-dd");
    const nextDueDate = p.due_date
      ? format(addMonths(parseISO(p.due_date), 1), "yyyy-MM-dd")
      : null;
    await supabase.from("payables").update({
      target_month: nextMonth,
      due_date: nextDueDate,
      completed_at: new Date().toISOString(),
    }).eq("id", p.id);
    toast({ title: `Moved "${p.vendor_name}" to ${format(addMonths(currentMonth, 1), "MMMM yyyy")}` });
    fetchData();
  };

  const filtered = payables.filter((p) =>
    p.vendor_name.toLowerCase().includes(search.toLowerCase()) ||
    (p.description || "").toLowerCase().includes(search.toLowerCase())
  );

  const totalAmount = filtered.reduce((s, p) => s + Number(p.amount || 0), 0);
  const pendingCount = filtered.filter(p => p.status === "pending").length;
  const fmtCurrency = (v: number) =>
    new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(v);

  return (
    <div className="space-y-6">
      {/* Header */}
      <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">
            <DollarSign className="h-6 w-6 text-primary" /> Payables
          </h1>
          <p className="text-sm text-muted-foreground mt-1">
            Monthly vendor invoices. Check off to move to next month.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <RecordImportButton
            title="Import Payables"
            description="Upload a CSV or Excel file with vendor payables. Map columns to fields before importing."
            expectedColumns={[
              { key: "vendor_name", label: "Vendor Name", required: true, aliases: ["vendor", "payee", "company"] },
              { key: "amount", label: "Amount", required: true, aliases: ["total", "invoice_amount", "amt"] },
              { key: "description", label: "Description", aliases: ["memo", "notes", "details"] },
              { key: "due_date", label: "Due Date", aliases: ["date_due", "payment_date", "date"] },
              { key: "status", label: "Status", aliases: ["payment_status"] },
              { key: "association_name", label: "Association", aliases: ["community", "hoa", "association"] },
            ]}
            onImport={async (rows) => {
              const assocMap = new Map(associations.map(a => [a.name.toLowerCase(), a.id]));
              const defaultAssocId = associations[0]?.id;
              const importMonthStr = format(currentMonth, "yyyy-MM-dd");

              const normalizeDate = (val: string | null | undefined): string | null => {
                if (!val) return null;
                const trimmed = val.trim();
                // Handle YYYY-MM format by appending -01
                if (/^\d{4}-\d{2}$/.test(trimmed)) return `${trimmed}-01`;
                // Handle YYYY-MM-DD or other valid formats
                if (/^\d{4}-\d{2}-\d{2}/.test(trimmed)) return trimmed.slice(0, 10);
                return trimmed;
              };

              const records = rows.map(row => {
                const matchedAssocId = row.association_name
                  ? assocMap.get(row.association_name.toLowerCase()) || defaultAssocId
                  : defaultAssocId;
                return {
                  vendor_name: row.vendor_name?.trim() || "Unknown Vendor",
                  amount: parseFloat(row.amount?.replace(/[^0-9.\-]/g, "") || "0"),
                  description: row.description?.trim() || null,
                  due_date: normalizeDate(row.due_date),
                  status: ["pending", "approved", "paid"].includes(row.status?.toLowerCase()) ? row.status.toLowerCase() : "pending",
                  target_month: importMonthStr,
                  association_id: matchedAssocId,
                };
              }).filter(r => r.association_id);

              if (records.length === 0) {
                toast({ variant: "destructive", title: "No valid rows to import" });
                return;
              }

              const { error } = await supabase.from("payables").insert(records);
              if (error) throw error;
              toast({ title: `Imported ${records.length} payable(s)` });
              fetchData();
            }}
            templateFileName="payables_template.csv"
            label="Import CSV"
          />
          <Button className="gap-2" onClick={openNew}><Plus className="h-4 w-4" /> New Payable</Button>
        </div>
      </div>

      {/* Month navigation */}
      <div className="flex items-center justify-between">
        <Button variant="outline" size="icon" onClick={() => setCurrentMonth(prev => subMonths(prev, 1))}>
          <ChevronLeft className="h-4 w-4" />
        </Button>
        <h2 className="text-lg font-semibold">{format(currentMonth, "MMMM yyyy")}</h2>
        <Button variant="outline" size="icon" onClick={() => setCurrentMonth(prev => addMonths(prev, 1))}>
          <ChevronRight className="h-4 w-4" />
        </Button>
      </div>

      {/* Summary cards */}
      <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
        <Card>
          <CardContent className="pt-4 pb-3 flex items-center justify-between">
            <div><p className="text-xs text-muted-foreground font-medium">Total Due</p><p className="text-xl font-bold">{fmtCurrency(totalAmount)}</p></div>
            <DollarSign className="h-8 w-8 text-primary/30" />
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-4 pb-3 flex items-center justify-between">
            <div><p className="text-xs text-muted-foreground font-medium">Invoices</p><p className="text-xl font-bold">{filtered.length}</p></div>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-4 pb-3 flex items-center justify-between">
            <div><p className="text-xs text-muted-foreground font-medium">Pending</p><p className="text-xl font-bold">{pendingCount}</p></div>
          </CardContent>
        </Card>
      </div>

      {/* Search */}
      <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 vendor or description..." className="pl-10" value={search} onChange={(e) => setSearch(e.target.value)} />
      </div>

      {/* 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>
      ) : filtered.length === 0 ? (
        <Card>
          <CardContent className="py-12 text-center text-muted-foreground">
            No payables for {format(currentMonth, "MMMM yyyy")}.
          </CardContent>
        </Card>
      ) : (
        <Card>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-12">Done</TableHead>
                <TableHead>Vendor</TableHead>
                <TableHead>Association</TableHead>
                <TableHead>Due Date</TableHead>
                <TableHead className="text-right">Amount</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="max-w-48">Description</TableHead>
                <TableHead className="w-12" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.map((p) => (
                <TableRow key={p.id} className="group">
                  <TableCell>
                    <Checkbox
                      onCheckedChange={() => handleCheckOff(p)}
                      title="Check off — moves to next month"
                    />
                  </TableCell>
                  <TableCell className="font-medium">{p.vendor_name}</TableCell>
                  <TableCell className="text-sm text-muted-foreground">{p.associations?.name || "—"}</TableCell>
                  <TableCell>
                    {p.due_date ? format(parseISO(p.due_date), "MMM d, yyyy") : "—"}
                  </TableCell>
                  <TableCell className="text-right font-semibold">{fmtCurrency(Number(p.amount))}</TableCell>
                  <TableCell>
                    <Badge className={`${statusColors[p.status] || "bg-muted text-muted-foreground"} border-0`}>
                      {p.status}
                    </Badge>
                  </TableCell>
                  <TableCell className="max-w-48 truncate text-sm text-muted-foreground">{p.description || "—"}</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(p)}>
                          <Edit className="h-4 w-4 mr-2" /> Edit
                        </DropdownMenuItem>
                        <DropdownMenuItem className="text-destructive" onClick={() => handleDelete(p.id)}>
                          <Trash2 className="h-4 w-4 mr-2" /> Delete
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </Card>
      )}

      {/* Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>{editing ? "Edit" : "New"} Payable</DialogTitle></DialogHeader>
          <div className="space-y-4">
            {!editing && (
              <div>
                <Label>Association</Label>
                <Select value={form.association_id} onValueChange={(v) => setForm({ ...form, association_id: v })}>
                  <SelectTrigger><SelectValue placeholder="Select..." /></SelectTrigger>
                  <SelectContent>
                    {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                  </SelectContent>
                </Select>
              </div>
            )}
            <div>
              <Label>Vendor</Label>
              <Input value={form.vendor_name} onChange={(e) => setForm({ ...form, vendor_name: e.target.value })} />
            </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>Due Date</Label><Input type="date" value={form.due_date} onChange={(e) => setForm({ ...form, due_date: e.target.value })} /></div>
            </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>
                </SelectContent>
              </Select>
            </div>
            <div><Label>Description</Label><Textarea value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} /></div>
          </div>
          <DialogFooter><Button onClick={handleSave}>{editing ? "Update" : "Create"}</Button></DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
