import { useState } from "react";
import { accounting } from "@/lib/accountingClient";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import {
  Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,
} from "@/components/ui/dialog";
import { Loader2, Plus, Trash2 } from "lucide-react";
import { useToast } from "@/hooks/use-toast";

type Item = { description: string; quantity: number; rate: number };

interface Props {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  companyId: string;
  /** "invoices" or "bills" */
  table: "invoices" | "bills";
  /** "invoice" or "bill" */
  itemTable: "invoice_items" | "bill_items";
  /** Counterparty options: customers for invoices, vendors for bills */
  parties: Array<{ id: string; name: string }>;
  partyField: "customer_id" | "vendor_id";
  partyLabel: string;
  onSaved: () => void;
}

export default function AccountingDocumentForm({
  open, onOpenChange, companyId, table, itemTable, parties, partyField, partyLabel, onSaved,
}: Props) {
  const { toast } = useToast();
  const [saving, setSaving] = useState(false);
  const [partyId, setPartyId] = useState<string>("");
  const [number, setNumber] = useState("");
  const [issueDate, setIssueDate] = useState(new Date().toISOString().slice(0, 10));
  const [dueDate, setDueDate] = useState("");
  const [notes, setNotes] = useState("");
  const [items, setItems] = useState<Item[]>([{ description: "", quantity: 1, rate: 0 }]);

  const subtotal = items.reduce((s, i) => s + i.quantity * i.rate, 0);

  const reset = () => {
    setPartyId(""); setNumber(""); setIssueDate(new Date().toISOString().slice(0, 10));
    setDueDate(""); setNotes(""); setItems([{ description: "", quantity: 1, rate: 0 }]);
  };

  const handleSave = async () => {
    if (!number.trim() || items.length === 0) return;
    setSaving(true);
    const { data: doc, error } = await accounting.from(table).insert({
      company_id: companyId,
      [partyField]: partyId || null,
      number,
      issue_date: issueDate,
      due_date: dueDate || null,
      subtotal,
      tax: 0,
      total: subtotal,
      notes: notes || null,
    }).select().single();
    if (error || !doc) {
      toast({ title: "Failed to save", description: error?.message, variant: "destructive" });
      setSaving(false);
      return;
    }
    const lines = items
      .filter((i) => i.description.trim())
      .map((i) => ({
        [`${table === "invoices" ? "invoice" : "bill"}_id`]: (doc as any).id,
        description: i.description,
        quantity: i.quantity,
        rate: i.rate,
        amount: i.quantity * i.rate,
      }));
    if (lines.length) {
      const { error: e2 } = await accounting.from(itemTable).insert(lines);
      if (e2) toast({ title: "Saved, but line items failed", description: e2.message, variant: "destructive" });
    }
    toast({ title: `${table === "invoices" ? "Invoice" : "Bill"} created` });
    reset();
    onOpenChange(false);
    onSaved();
    setSaving(false);
  };

  return (
    <Dialog open={open} onOpenChange={(v) => { if (!v) reset(); onOpenChange(v); }}>
      <DialogContent className="max-w-3xl">
        <DialogHeader>
          <DialogTitle>New {table === "invoices" ? "Invoice" : "Bill"}</DialogTitle>
          <DialogDescription>Create a {table === "invoices" ? "customer invoice" : "vendor bill"} with line items.</DialogDescription>
        </DialogHeader>
        <div className="space-y-3">
          <div className="grid grid-cols-3 gap-3">
            <div className="space-y-1">
              <Label>{partyLabel}</Label>
              <Select value={partyId} onValueChange={setPartyId}>
                <SelectTrigger><SelectValue placeholder="Select…" /></SelectTrigger>
                <SelectContent>
                  {parties.map((p) => <SelectItem key={p.id} value={p.id}>{p.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1"><Label>Number</Label><Input value={number} onChange={(e) => setNumber(e.target.value)} placeholder="0001" /></div>
            <div className="grid grid-cols-2 gap-2">
              <div className="space-y-1"><Label>Date</Label><Input type="date" value={issueDate} onChange={(e) => setIssueDate(e.target.value)} /></div>
              <div className="space-y-1"><Label>Due</Label><Input type="date" value={dueDate} onChange={(e) => setDueDate(e.target.value)} /></div>
            </div>
          </div>

          <div className="border rounded-md">
            <div className="grid grid-cols-12 gap-2 px-3 py-2 text-xs font-medium text-muted-foreground border-b">
              <div className="col-span-6">Description</div>
              <div className="col-span-2 text-right">Qty</div>
              <div className="col-span-2 text-right">Rate</div>
              <div className="col-span-1 text-right">Amount</div>
              <div className="col-span-1"></div>
            </div>
            {items.map((it, idx) => (
              <div key={idx} className="grid grid-cols-12 gap-2 px-3 py-2 border-b last:border-b-0">
                <Input className="col-span-6" value={it.description} onChange={(e) => {
                  const next = [...items]; next[idx] = { ...it, description: e.target.value }; setItems(next);
                }} />
                <Input className="col-span-2 text-right" type="number" step="0.01" value={it.quantity} onChange={(e) => {
                  const next = [...items]; next[idx] = { ...it, quantity: Number(e.target.value) }; setItems(next);
                }} />
                <Input className="col-span-2 text-right" type="number" step="0.01" value={it.rate} onChange={(e) => {
                  const next = [...items]; next[idx] = { ...it, rate: Number(e.target.value) }; setItems(next);
                }} />
                <div className="col-span-1 text-right text-sm tabular-nums self-center">{(it.quantity * it.rate).toFixed(2)}</div>
                <Button type="button" variant="ghost" size="icon" className="col-span-1 h-8 w-8 justify-self-end"
                  onClick={() => setItems(items.filter((_, i) => i !== idx))} disabled={items.length === 1}>
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            ))}
            <div className="flex items-center justify-between px-3 py-2 bg-muted/30">
              <Button type="button" size="sm" variant="outline" className="gap-2"
                onClick={() => setItems([...items, { description: "", quantity: 1, rate: 0 }])}>
                <Plus className="h-3 w-3" /> Line
              </Button>
              <div className="text-sm">Total: <span className="font-semibold tabular-nums">${subtotal.toFixed(2)}</span></div>
            </div>
          </div>

          <div className="space-y-1"><Label>Notes</Label><Textarea rows={2} value={notes} onChange={(e) => setNotes(e.target.value)} /></div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
          <Button onClick={handleSave} disabled={saving || !number.trim()}>{saving ? <Loader2 className="h-4 w-4 animate-spin" /> : "Create"}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}