import { useState, useEffect } from "react";
import { Switch } from "@/components/ui/switch";
import { supabase } from "@/integrations/supabase/client";
import { generateHomeownerInvoicePdf } from "@/lib/generateHomeownerInvoicePdf";
import { useToast } from "@/hooks/use-toast";
import { format } from "date-fns";
import { combineOwnerNames, collectAllAddresses } from "@/lib/ownerAddressUtils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Plus, Trash2, FileText, Loader2 } from "lucide-react";

const DEFAULT_LINE = { id: Date.now(), description: "Assessment Fee", accountId: "", amount: 0 };

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  unitId: string;
  associationId: string;
  unitData: any;
  owners: any[];
  onSuccess?: () => void;
}

export default function UnitLedgerInvoiceDialog({ open, onOpenChange, unitId, associationId, unitData, owners, onSuccess }: Props) {
  const { toast } = useToast();
  const [generating, setGenerating] = useState(false);
  const [accounts, setAccounts] = useState<any[]>([]);
  const [companySettings, setCompanySettings] = useState<Record<string, string>>({});

  const [invoiceDate, setInvoiceDate] = useState(new Date().toISOString().split("T")[0]);
  const [dueDate, setDueDate] = useState("");
  const [billingPeriod, setBillingPeriod] = useState("");
  const [invoiceNumber, setInvoiceNumber] = useState("");
  const [notes, setNotes] = useState("Thank you for your prompt payment.");
  const [lineItems, setLineItems] = useState([{ ...DEFAULT_LINE }]);
  const [useCompanyAsSender, setUseCompanyAsSender] = useState(false);

  const primaryOwner = owners.find((o: any) => o.is_primary) || owners[0];
  const assoc = unitData?.associations;

  useEffect(() => {
    if (!open || !associationId) return;

    // Filter the COA to the association's accounting system (zoho vs buildium).
    (async () => {
      const { data: assocRow } = await supabase
        .from("associations")
        .select("zoho_organization_id")
        .eq("id", associationId)
        .maybeSingle();
      const system = assocRow?.zoho_organization_id ? "zoho" : "buildium";

      const { data } = await supabase
        .from("chart_of_accounts")
        .select("id, account_number, account_name, account_type")
        .eq("accounting_system", system)
        .eq("is_active", true)
        .order("account_number");
      setAccounts(data || []);
    })();

    supabase.from("company_settings").select("key, value")
      .then(({ data }) => {
        const s: Record<string, string> = {};
        (data || []).forEach((r: any) => { s[r.key] = r.value; });
        setCompanySettings(s);
      });

    // Auto invoice number
    supabase.from("client_invoices").select("invoice_number")
      .order("created_at", { ascending: false }).limit(1)
      .then(({ data }) => {
        if (data?.[0]?.invoice_number) {
          const match = data[0].invoice_number.match(/(\d+)$/);
          if (match) {
            setInvoiceNumber(`INV-${String(parseInt(match[1]) + 1).padStart(4, "0")}`);
            return;
          }
        }
        setInvoiceNumber("INV-1001");
      });
  }, [open, associationId]);

  const addLine = () => setLineItems([...lineItems, { id: Date.now(), description: "", accountId: "", amount: 0 }]);
  const updateLine = (id: number, field: string, value: any) => setLineItems(lineItems.map(li => li.id === id ? { ...li, [field]: value } : li));
  const removeLine = (id: number) => { if (lineItems.length > 1) setLineItems(lineItems.filter(li => li.id !== id)); };
  const total = lineItems.reduce((s, li) => s + (Number(li.amount) || 0), 0);

  const handleGenerate = async () => {
    if (!primaryOwner) {
      toast({ variant: "destructive", title: "No owner assigned to this unit" });
      return;
    }
    if (!lineItems.some(li => li.description && li.amount > 0)) {
      toast({ variant: "destructive", title: "Add at least one line item with an amount" });
      return;
    }

    setGenerating(true);
    try {
      const user = (await supabase.auth.getUser()).data.user;

      // Save invoice record
      const { data: invData } = await supabase.from("client_invoices").insert({
        invoice_number: invoiceNumber,
        association_id: associationId,
        amount: total,
        credits: 0,
        total: total,
        status: "sent",
        issue_date: invoiceDate || new Date().toISOString().split("T")[0],
        due_date: dueDate || null,
        source: "unit_ledger",
        notes: notes || null,
        created_by: user?.id,
      }).select().single();

      if (invData) {
        await supabase.from("client_invoice_items").insert(
          lineItems.filter(li => li.description).map(li => ({
            invoice_id: invData.id,
            description: li.description,
            quantity: 1,
            unit_price: Number(li.amount || 0),
            amount: Number(li.amount || 0),
            is_credit: false,
          }))
        );
      }

      // Also post charges to the unit ledger
      for (const li of lineItems.filter(l => l.description && l.amount > 0)) {
        await supabase.from("owner_ledger_entries").insert({
          unit_id: unitId,
          association_id: associationId,
          owner_id: primaryOwner.id,
          date: invoiceDate,
          description: `Invoice ${invoiceNumber}: ${li.description}`,
          transaction_type: "Charge",
          debit: Number(li.amount),
          credit: 0,
          created_by: user?.id,
        });
      }

      // Generate PDF for each address, addressed to ALL owners
      const combinedName = combineOwnerNames(owners);
      const allAddresses = collectAllAddresses(owners);
      const ownerAddr = primaryOwner.property_address || primaryOwner.street_address || unitData?.address || "";

      for (const addrCopy of allAddresses) {
        await generateHomeownerInvoicePdf({
          invoiceNumber,
          invoiceDate: invoiceDate ? format(new Date(invoiceDate), "yyyy-MM-dd") : "",
          dueDate: dueDate ? format(new Date(dueDate), "yyyy-MM-dd") : "",
          billingPeriod,
          associationName: assoc?.name || "",
          associationCareOf: assoc?.care_of_address || "",
          associationMailingAddress: assoc?.mailing_address || "",
          companyName: companySettings.company_name || "Avria Community Management",
          companyAddress: companySettings.company_address || "",
          useCompanyAsSender,
          ownerName: combinedName,
          ownerAddress: ownerAddr,
          ownerMailingAddress: addrCopy.address,
          accountNumber: unitData?.account_number || "",
          items: lineItems.filter(li => li.description).map(li => ({
            description: li.description,
            amount: Number(li.amount || 0),
          })),
          notes,
          logoUrl: assoc?.logo_url || null,
        });
      }

      toast({ title: "Invoice generated & saved" });
      onSuccess?.();
      onOpenChange(false);
    } catch (err: any) {
      toast({ variant: "destructive", title: "Error", description: err.message });
    } finally {
      setGenerating(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <FileText className="h-5 w-5 text-primary" /> Generate Invoice — Unit {unitData?.unit_number || ""}
          </DialogTitle>
        </DialogHeader>

        <div className="space-y-4 mt-2">
          {/* Owner info */}
          <div className="bg-muted/50 rounded-lg p-3 text-sm">
            <p className="font-medium">{primaryOwner ? `${primaryOwner.first_name} ${primaryOwner.last_name}` : "No owner"}</p>
            <p className="text-muted-foreground">{assoc?.name || "Association"} — Unit {unitData?.unit_number || "N/A"}</p>
          </div>

          {/* Invoice details */}
          <div className="grid grid-cols-4 gap-3">
            <div className="space-y-1">
              <Label className="text-xs">Invoice Date</Label>
              <Input type="date" value={invoiceDate} onChange={(e) => setInvoiceDate(e.target.value)} className="text-sm h-9" />
            </div>
            <div className="space-y-1">
              <Label className="text-xs">Due Date</Label>
              <Input type="date" value={dueDate} onChange={(e) => setDueDate(e.target.value)} className="text-sm h-9" />
            </div>
            <div className="space-y-1">
              <Label className="text-xs">Billing Period</Label>
              <Input placeholder="e.g. Jan 2026" value={billingPeriod} onChange={(e) => setBillingPeriod(e.target.value)} className="text-sm h-9" />
            </div>
            <div className="space-y-1">
              <Label className="text-xs">Invoice #</Label>
              <Input value={invoiceNumber} onChange={(e) => setInvoiceNumber(e.target.value)} className="text-sm h-9" />
            </div>
          </div>

          {/* Sender toggle */}
          <div className="flex items-center gap-2">
            <Switch checked={useCompanyAsSender} onCheckedChange={setUseCompanyAsSender} />
            <Label className="text-xs text-muted-foreground">Send from company address instead of association</Label>
          </div>

          {/* Line Items */}
          <div>
            <div className="flex items-center justify-between mb-2">
              <span className="text-sm font-semibold">Line Items</span>
              <Button variant="outline" size="sm" className="gap-1.5 text-xs h-7" onClick={addLine}>
                <Plus className="h-3 w-3" /> Add Item
              </Button>
            </div>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="text-xs">Description</TableHead>
                  <TableHead className="text-xs">Account</TableHead>
                  <TableHead className="text-xs w-[110px]">Amount ($)</TableHead>
                  <TableHead className="w-8" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {lineItems.map((li) => (
                  <TableRow key={li.id}>
                    <TableCell>
                      <Input value={li.description} onChange={(e) => updateLine(li.id, "description", e.target.value)} className="text-sm h-8" placeholder="Item description" />
                    </TableCell>
                    <TableCell>
                      <Select value={li.accountId} onValueChange={(v) => updateLine(li.id, "accountId", v)}>
                        <SelectTrigger className="text-xs h-8"><SelectValue placeholder="Account..." /></SelectTrigger>
                        <SelectContent>
                          {accounts.map(a => (
                            <SelectItem key={a.id} value={a.id}>
                              <span className="font-mono text-[11px] mr-1">{a.account_number}</span> {a.account_name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </TableCell>
                    <TableCell>
                      <Input type="number" step="0.01" value={li.amount || ""} onChange={(e) => updateLine(li.id, "amount", e.target.value)} className="text-sm h-8" />
                    </TableCell>
                    <TableCell>
                      <Button variant="ghost" size="icon" className="h-7 w-7" onClick={() => removeLine(li.id)} disabled={lineItems.length <= 1}>
                        <Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
            <div className="flex justify-end mt-2 text-sm font-bold pr-16">
              Total: ${total.toFixed(2)}
            </div>
          </div>

          {/* Notes */}
          <div className="space-y-1">
            <Label className="text-xs">Notes</Label>
            <Textarea value={notes} onChange={(e) => setNotes(e.target.value)} rows={2} className="text-sm" />
          </div>

          <Button className="w-full gap-2" onClick={handleGenerate} disabled={generating}>
            {generating ? <Loader2 className="h-4 w-4 animate-spin" /> : <FileText className="h-4 w-4" />}
            Generate Invoice
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
