import { useState, useEffect, useCallback } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { DollarSign, Plus, MoreHorizontal, Edit, Trash2, Check, ChevronDown, ChevronRight, CalendarCheck } 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, DialogDescription } 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 { Checkbox } from "@/components/ui/checkbox";
import { useAuth } from "@/contexts/AuthContext";
import { format } from "date-fns";

export default function PaymentPlansPage() {
  const { toast } = useToast();
  const { user } = useAuth();
  const [plans, setPlans] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [associations, setAssociations] = useState<any[]>([]);
  const [owners, setOwners] = useState<any[]>([]);
  const [units, setUnits] = useState<any[]>([]);
  const [expandedPlan, setExpandedPlan] = useState<string | null>(null);
  const [installments, setInstallments] = useState<Record<string, any[]>>({});

  const [form, setForm] = useState({
    association_id: "",
    owner_id: "",
    unit_id: "",
    total_amount: "",
    monthly_payment: "",
    start_date: "",
    end_date: "",
    status: "active",
    notes: "",
  });

  const fetchData = useCallback(async () => {
    setLoading(true);
    const { data } = await supabase
      .from("payment_plans")
      .select("*, associations(name), owners(first_name, last_name), units:unit_id(unit_number, address)")
      .order("created_at", { ascending: false });
    setPlans(data || []);
    setLoading(false);
  }, []);

  const fetchAssociations = useCallback(async () => {
    const { data } = await supabase.from("associations").select("id, name").eq("status", "active").order("name");
    setAssociations(data || []);
  }, []);

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

  // Load owners and units when association changes
  const loadAssociationData = useCallback(async (assocId: string) => {
    if (!assocId) { setOwners([]); setUnits([]); return; }
    const [ownersRes, unitsRes] = await Promise.all([
      supabase.from("owners").select("id, first_name, last_name, account_number").eq("association_id", assocId).eq("status", "active").order("last_name"),
      supabase.from("units").select("id, unit_number, address").eq("association_id", assocId).order("unit_number"),
    ]);
    setOwners(ownersRes.data || []);
    setUnits(unitsRes.data || []);
  }, []);

  const openNew = () => {
    setEditing(null);
    setForm({ association_id: "", owner_id: "", unit_id: "", total_amount: "", monthly_payment: "", start_date: "", end_date: "", status: "active", notes: "" });
    setOwners([]);
    setUnits([]);
    setDialogOpen(true);
  };

  const openEdit = (p: any) => {
    setEditing(p);
    setForm({
      association_id: p.association_id || "",
      owner_id: p.owner_id || "",
      unit_id: p.unit_id || "",
      total_amount: p.total_amount?.toString() || "",
      monthly_payment: p.monthly_payment?.toString() || "",
      start_date: p.start_date || "",
      end_date: p.end_date || "",
      status: p.status,
      notes: p.notes || "",
    });
    if (p.association_id) loadAssociationData(p.association_id);
    setDialogOpen(true);
  };

  const handleSave = async () => {
    if (!form.association_id) {
      toast({ variant: "destructive", title: "Error", description: "Please select an association." });
      return;
    }
    const payload: any = {
      association_id: form.association_id,
      owner_id: form.owner_id || null,
      unit_id: form.unit_id || null,
      total_amount: parseFloat(form.total_amount) || 0,
      monthly_payment: parseFloat(form.monthly_payment) || 0,
      start_date: form.start_date || null,
      end_date: form.end_date || null,
      status: form.status,
      notes: form.notes || null,
    };

    if (editing) {
      await supabase.from("payment_plans").update(payload).eq("id", editing.id);
      toast({ title: "Updated" });
    } else {
      payload.created_by = user?.id;
      const { data, error } = await supabase.from("payment_plans").insert(payload).select().single();
      if (error) { toast({ variant: "destructive", title: "Error", description: error.message }); return; }
      // Auto-generate installments if we have monthly payment and start/end dates
      if (data && form.start_date && form.end_date && parseFloat(form.monthly_payment) > 0) {
        await generateInstallments(data.id, form.start_date, form.end_date, parseFloat(form.monthly_payment));
      }
      toast({ title: "Plan created" });
    }
    setDialogOpen(false);
    fetchData();
  };

  const generateInstallments = async (planId: string, startDate: string, endDate: string, monthlyAmount: number) => {
    const installmentRows: any[] = [];
    let current = new Date(startDate + "T00:00:00");
    const end = new Date(endDate + "T00:00:00");
    let num = 1;
    while (current <= end) {
      installmentRows.push({
        payment_plan_id: planId,
        installment_number: num,
        due_date: current.toISOString().split("T")[0],
        amount_due: monthlyAmount,
        status: "pending",
      });
      num++;
      current.setMonth(current.getMonth() + 1);
    }
    if (installmentRows.length > 0) {
      await supabase.from("payment_plan_installments").insert(installmentRows);
    }
  };

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

  // Fetch installments for a plan
  const fetchInstallments = async (planId: string) => {
    const { data } = await supabase
      .from("payment_plan_installments")
      .select("*")
      .eq("payment_plan_id", planId)
      .order("installment_number");
    setInstallments((prev) => ({ ...prev, [planId]: data || [] }));
  };

  const toggleExpand = (planId: string) => {
    if (expandedPlan === planId) {
      setExpandedPlan(null);
    } else {
      setExpandedPlan(planId);
      if (!installments[planId]) fetchInstallments(planId);
    }
  };

  // Mark installment as paid
  const markInstallmentPaid = async (inst: any) => {
    const newStatus = inst.status === "paid" ? "pending" : "paid";
    const updates: any = {
      status: newStatus,
      paid_date: newStatus === "paid" ? new Date().toISOString().split("T")[0] : null,
      amount_paid: newStatus === "paid" ? inst.amount_due : 0,
    };
    await supabase.from("payment_plan_installments").update(updates).eq("id", inst.id);
    fetchInstallments(inst.payment_plan_id);
    toast({ title: newStatus === "paid" ? "Marked as Paid" : "Marked as Pending" });
  };

  // Add a single installment
  const [addInstDialog, setAddInstDialog] = useState<string | null>(null);
  const [instForm, setInstForm] = useState({ due_date: "", amount_due: "" });

  const handleAddInstallment = async () => {
    if (!addInstDialog) return;
    const existing = installments[addInstDialog] || [];
    const nextNum = existing.length > 0 ? Math.max(...existing.map((i: any) => i.installment_number)) + 1 : 1;
    await supabase.from("payment_plan_installments").insert({
      payment_plan_id: addInstDialog,
      installment_number: nextNum,
      due_date: instForm.due_date,
      amount_due: parseFloat(instForm.amount_due) || 0,
      status: "pending",
    });
    fetchInstallments(addInstDialog);
    setAddInstDialog(null);
    setInstForm({ due_date: "", amount_due: "" });
    toast({ title: "Installment added" });
  };

  const statusColors: Record<string, string> = {
    active: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300",
    completed: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300",
    defaulted: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300",
  };

  const fmt = (n: number) => `$${Number(n).toLocaleString(undefined, { minimumFractionDigits: 2 })}`;

  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">
            <DollarSign className="h-6 w-6 text-primary" /> Payment Plans
          </h1>
          <p className="text-sm text-muted-foreground mt-1">Set up and manage installment payment plans.</p>
        </div>
        <Button className="gap-2" onClick={openNew}><Plus className="h-4 w-4" /> New Plan</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>
      ) : plans.length === 0 ? (
        <Card><CardContent className="py-12 text-center text-muted-foreground">No payment plans found.</CardContent></Card>
      ) : (
        <Card>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-8" />
                <TableHead>Owner</TableHead>
                <TableHead>Property</TableHead>
                <TableHead>Association</TableHead>
                <TableHead>Total</TableHead>
                <TableHead>Monthly</TableHead>
                <TableHead>Progress</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="w-12" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {plans.map((p) => {
                const isExpanded = expandedPlan === p.id;
                const planInstallments = installments[p.id] || [];
                const paidCount = planInstallments.filter((i: any) => i.status === "paid").length;
                const totalCount = planInstallments.length;
                const paidAmount = planInstallments.reduce((sum: number, i: any) => sum + Number(i.amount_paid || 0), 0);

                return (
                  <>
                    <TableRow key={p.id} className="cursor-pointer hover:bg-muted/50" onClick={() => toggleExpand(p.id)}>
                      <TableCell>
                        {isExpanded ? <ChevronDown className="h-4 w-4 text-muted-foreground" /> : <ChevronRight className="h-4 w-4 text-muted-foreground" />}
                      </TableCell>
                      <TableCell className="font-medium">
                        {p.owners ? `${p.owners.first_name} ${p.owners.last_name}` : <span className="text-muted-foreground">—</span>}
                      </TableCell>
                      <TableCell>
                        {p.units ? (p.units.unit_number || p.units.address) : <span className="text-muted-foreground">—</span>}
                      </TableCell>
                      <TableCell className="text-sm">{p.associations?.name || "—"}</TableCell>
                      <TableCell>{fmt(p.total_amount)}</TableCell>
                      <TableCell>{fmt(p.monthly_payment)}</TableCell>
                      <TableCell>
                        {totalCount > 0 ? (
                          <div className="flex items-center gap-2">
                            <div className="flex-1 h-2 bg-muted rounded-full overflow-hidden max-w-[80px]">
                              <div className="h-full bg-primary rounded-full transition-all" style={{ width: `${(paidCount / totalCount) * 100}%` }} />
                            </div>
                            <span className="text-xs text-muted-foreground">{paidCount}/{totalCount}</span>
                          </div>
                        ) : (
                          <span className="text-xs text-muted-foreground">No installments</span>
                        )}
                      </TableCell>
                      <TableCell><Badge className={statusColors[p.status] || "bg-muted text-muted-foreground"}>{p.status}</Badge></TableCell>
                      <TableCell onClick={(e) => e.stopPropagation()}>
                        <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>

                    {/* Expanded installments */}
                    {isExpanded && (
                      <TableRow key={`${p.id}-inst`}>
                        <TableCell colSpan={9} className="bg-muted/20 p-0">
                          <div className="px-6 py-4 space-y-3">
                            <div className="flex items-center justify-between">
                              <h3 className="text-sm font-semibold text-foreground flex items-center gap-2">
                                <CalendarCheck className="h-4 w-4" /> Payment Schedule
                                {totalCount > 0 && <span className="text-muted-foreground font-normal">— {fmt(paidAmount)} paid of {fmt(p.total_amount)}</span>}
                              </h3>
                              <Button size="sm" variant="outline" className="gap-1.5 text-xs" onClick={() => { setAddInstDialog(p.id); setInstForm({ due_date: "", amount_due: p.monthly_payment?.toString() || "" }); }}>
                                <Plus className="h-3 w-3" /> Add Installment
                              </Button>
                            </div>

                            {planInstallments.length === 0 ? (
                              <p className="text-sm text-muted-foreground py-2">No installments yet. Add installments or they'll be auto-generated when creating a new plan with start/end dates.</p>
                            ) : (
                              <Table>
                                <TableHeader>
                                  <TableRow>
                                    <TableHead className="w-8">#</TableHead>
                                    <TableHead>Due Date</TableHead>
                                    <TableHead>Amount Due</TableHead>
                                    <TableHead>Amount Paid</TableHead>
                                    <TableHead>Paid Date</TableHead>
                                    <TableHead>Status</TableHead>
                                    <TableHead className="w-24">Action</TableHead>
                                  </TableRow>
                                </TableHeader>
                                <TableBody>
                                  {planInstallments.map((inst: any) => (
                                    <TableRow key={inst.id} className={inst.status === "paid" ? "bg-emerald-50/50 dark:bg-emerald-900/10" : ""}>
                                      <TableCell className="text-xs text-muted-foreground">{inst.installment_number}</TableCell>
                                      <TableCell className="text-sm">{inst.due_date ? format(new Date(inst.due_date + "T00:00:00"), "MMM d, yyyy") : "—"}</TableCell>
                                      <TableCell className="text-sm">{fmt(inst.amount_due)}</TableCell>
                                      <TableCell className="text-sm">{inst.amount_paid > 0 ? fmt(inst.amount_paid) : "—"}</TableCell>
                                      <TableCell className="text-sm">{inst.paid_date ? format(new Date(inst.paid_date + "T00:00:00"), "MMM d, yyyy") : "—"}</TableCell>
                                      <TableCell>
                                        <Badge className={inst.status === "paid" ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300" : "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300"}>
                                          {inst.status}
                                        </Badge>
                                      </TableCell>
                                      <TableCell>
                                        <Button
                                          size="sm"
                                          variant={inst.status === "paid" ? "outline" : "default"}
                                          className="gap-1 text-xs h-7"
                                          onClick={() => markInstallmentPaid(inst)}
                                        >
                                          <Check className="h-3 w-3" />
                                          {inst.status === "paid" ? "Undo" : "Paid"}
                                        </Button>
                                      </TableCell>
                                    </TableRow>
                                  ))}
                                </TableBody>
                              </Table>
                            )}
                          </div>
                        </TableCell>
                      </TableRow>
                    )}
                  </>
                );
              })}
            </TableBody>
          </Table>
        </Card>
      )}

      {/* Create / Edit Plan Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit" : "New"} Payment Plan</DialogTitle>
            <DialogDescription>Configure the payment plan details, owner, and property.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            {/* Association */}
            <div>
              <Label className="text-xs">Association</Label>
              <Select
                value={form.association_id}
                onValueChange={(v) => {
                  setForm({ ...form, association_id: v, owner_id: "", unit_id: "" });
                  loadAssociationData(v);
                }}
              >
                <SelectTrigger className="h-9 text-sm"><SelectValue placeholder="Select association" /></SelectTrigger>
                <SelectContent>
                  {associations.map((a) => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>

            {/* Owner & Unit */}
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="text-xs">Owner</Label>
                <Select value={form.owner_id} onValueChange={(v) => setForm({ ...form, owner_id: v })}>
                  <SelectTrigger className="h-9 text-sm"><SelectValue placeholder="Select owner" /></SelectTrigger>
                  <SelectContent>
                    {owners.map((o) => (
                      <SelectItem key={o.id} value={o.id}>
                        {o.last_name}, {o.first_name} {o.account_number ? `(${o.account_number})` : ""}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div>
                <Label className="text-xs">Property / Unit</Label>
                <Select value={form.unit_id} onValueChange={(v) => setForm({ ...form, unit_id: v })}>
                  <SelectTrigger className="h-9 text-sm"><SelectValue placeholder="Select unit" /></SelectTrigger>
                  <SelectContent>
                    {units.map((u) => (
                      <SelectItem key={u.id} value={u.id}>
                        {u.unit_number || u.address}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            {/* Amounts */}
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="text-xs">Total Amount</Label>
                <Input type="number" value={form.total_amount} onChange={(e) => setForm({ ...form, total_amount: e.target.value })} className="h-9 text-sm" />
              </div>
              <div>
                <Label className="text-xs">Monthly Payment</Label>
                <Input type="number" value={form.monthly_payment} onChange={(e) => setForm({ ...form, monthly_payment: e.target.value })} className="h-9 text-sm" />
              </div>
            </div>

            {/* Dates */}
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="text-xs">Start Date</Label>
                <Input type="date" value={form.start_date} onChange={(e) => setForm({ ...form, start_date: e.target.value })} className="h-9 text-sm" />
              </div>
              <div>
                <Label className="text-xs">End Date</Label>
                <Input type="date" value={form.end_date} onChange={(e) => setForm({ ...form, end_date: e.target.value })} className="h-9 text-sm" />
              </div>
            </div>

            {/* Status */}
            <div>
              <Label className="text-xs">Status</Label>
              <Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}>
                <SelectTrigger className="h-9 text-sm"><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="completed">Completed</SelectItem>
                  <SelectItem value="defaulted">Defaulted</SelectItem>
                </SelectContent>
              </Select>
            </div>

            {/* Notes */}
            <div>
              <Label className="text-xs">Notes</Label>
              <Textarea value={form.notes} onChange={(e) => setForm({ ...form, notes: e.target.value })} rows={2} className="text-sm" />
            </div>

            {!editing && form.start_date && form.end_date && parseFloat(form.monthly_payment) > 0 && (
              <p className="text-xs text-muted-foreground bg-muted/50 rounded p-2">
                💡 Installments will be auto-generated monthly from {form.start_date} to {form.end_date}.
              </p>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleSave}>{editing ? "Update" : "Create"}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Add Installment Dialog */}
      <Dialog open={!!addInstDialog} onOpenChange={() => setAddInstDialog(null)}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Add Installment</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label className="text-xs">Due Date</Label>
              <Input type="date" value={instForm.due_date} onChange={(e) => setInstForm({ ...instForm, due_date: e.target.value })} className="h-9 text-sm" />
            </div>
            <div>
              <Label className="text-xs">Amount Due</Label>
              <Input type="number" value={instForm.amount_due} onChange={(e) => setInstForm({ ...instForm, amount_due: e.target.value })} className="h-9 text-sm" />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setAddInstDialog(null)}>Cancel</Button>
            <Button onClick={handleAddInstallment} disabled={!instForm.due_date}>Add</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
