import { useEffect, useMemo, useState } from "react";
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 { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Textarea } from "@/components/ui/textarea";
import { Loader2, Search, Trash2 } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";

type Vendor = {
  id: string;
  name: string;
  contact_name: string | null;
  email: string | null;
  phone: string | null;
  address: string | null;
  tax_id: string | null;
  payment_terms: string | null;
  is_1099_eligible: boolean | null;
  is_active: boolean | null;
};

type EditableVendor = Vendor & { _dirty?: boolean; _delete?: boolean };

interface Props {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  vendors: Vendor[];
  onSaved: () => void;
}

const FIELDS: Array<{ key: keyof Vendor; label: string; type: "text" | "checkbox" | "textarea"; width: string }> = [
  { key: "name", label: "Vendor Name", type: "text", width: "min-w-[180px]" },
  { key: "contact_name", label: "Contact", type: "text", width: "min-w-[140px]" },
  { key: "email", label: "Email", type: "text", width: "min-w-[180px]" },
  { key: "phone", label: "Phone", type: "text", width: "min-w-[130px]" },
  { key: "address", label: "Address", type: "textarea", width: "min-w-[220px]" },
  { key: "tax_id", label: "Tax ID", type: "text", width: "min-w-[120px]" },
  { key: "payment_terms", label: "Terms (days)", type: "text", width: "min-w-[100px]" },
  { key: "is_1099_eligible", label: "1099", type: "checkbox", width: "w-[60px]" },
  { key: "is_active", label: "Active", type: "checkbox", width: "w-[70px]" },
];

export function BulkVendorEditDialog({ open, onOpenChange, vendors, onSaved }: Props) {
  const { toast } = useToast();
  const [rows, setRows] = useState<EditableVendor[]>([]);
  const [search, setSearch] = useState("");
  const [saving, setSaving] = useState(false);
  const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);

  useEffect(() => {
    if (open) {
      setRows(vendors.map((v) => ({ ...v })));
      setSearch("");
    }
  }, [open, vendors]);

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return rows;
    return rows.filter((r) =>
      [r.name, r.contact_name, r.email, r.phone, r.address, r.tax_id]
        .some((f) => (f || "").toLowerCase().includes(q))
    );
  }, [rows, search]);

  const dirtyCount = rows.filter((r) => r._dirty && !r._delete).length;
  const deleteCount = rows.filter((r) => r._delete).length;

  const updateCell = (id: string, key: keyof Vendor, value: any) => {
    setRows((prev) => prev.map((r) => (r.id === id ? { ...r, [key]: value, _dirty: true } : r)));
  };

  const toggleDelete = (id: string, value: boolean) => {
    setRows((prev) => prev.map((r) => (r.id === id ? { ...r, _delete: value } : r)));
  };

  const performSave = async () => {
    const dirty = rows.filter((r) => r._dirty && !r._delete);
    const toDelete = rows.filter((r) => r._delete);

    if (dirty.length === 0 && toDelete.length === 0) {
      toast({ title: "No changes to save" });
      return;
    }

    setSaving(true);
    let updated = 0;
    let deleted = 0;
    let failed = 0;
    const failedDeletes: string[] = [];

    for (const r of dirty) {
      const { _dirty, _delete, id, ...payload } = r as any;
      const clean = {
        name: payload.name,
        contact_name: payload.contact_name || null,
        email: payload.email || null,
        phone: payload.phone || null,
        address: payload.address || null,
        tax_id: payload.tax_id || null,
        payment_terms: payload.payment_terms || null,
        is_1099_eligible: !!payload.is_1099_eligible,
        is_active: !!payload.is_active,
      };
      const { error } = await supabase.from("vendors").update(clean).eq("id", id);
      if (error) failed++; else updated++;
    }

    for (const r of toDelete) {
      const { error } = await supabase.from("vendors").delete().eq("id", r.id);
      if (error) {
        failed++;
        failedDeletes.push(r.name);
      } else {
        deleted++;
      }
    }

    setSaving(false);
    setConfirmDeleteOpen(false);

    const parts: string[] = [];
    if (updated) parts.push(`Updated ${updated}`);
    if (deleted) parts.push(`Deleted ${deleted}`);
    if (failed) parts.push(`Failed ${failed}`);

    toast({
      title: "Bulk update complete",
      description: parts.join(", ") + (failedDeletes.length ? ` (couldn't delete: ${failedDeletes.join(", ")} — likely referenced by bills/invoices)` : "."),
      variant: failed ? "destructive" : "default",
    });
    onSaved();
    onOpenChange(false);
  };

  const handleSave = () => {
    if (deleteCount > 0) {
      setConfirmDeleteOpen(true);
    } else {
      performSave();
    }
  };

  const totalChanges = dirtyCount + deleteCount;

  return (
    <>
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[95vw] w-[95vw] max-h-[90vh] flex flex-col">
        <DialogHeader>
          <DialogTitle>Bulk Edit Vendors</DialogTitle>
          <DialogDescription>
            Edit any field inline, or check the Delete column to remove vendors. Click "Save Changes" to apply all edits at once.
          </DialogDescription>
        </DialogHeader>

        <div className="flex items-center gap-2 pb-2">
          <div className="relative w-full max-w-sm">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search vendors..."
              className="pl-10"
            />
          </div>
          <div className="ml-auto text-sm text-muted-foreground flex items-center gap-3">
            {dirtyCount > 0 && (
              <span className="text-foreground font-medium">{dirtyCount} edit{dirtyCount === 1 ? "" : "s"}</span>
            )}
            {deleteCount > 0 && (
              <span className="text-destructive font-medium">{deleteCount} to delete</span>
            )}
            {totalChanges === 0 && (
              <span>{filtered.length} vendor{filtered.length === 1 ? "" : "s"}</span>
            )}
          </div>
        </div>

        <div className="flex-1 overflow-auto border border-border rounded-md">
          <table className="w-full text-sm border-collapse">
            <thead className="sticky top-0 bg-muted z-10">
              <tr>
                {FIELDS.map((f) => (
                  <th
                    key={f.key as string}
                    className={`text-left font-semibold px-2 py-2 border-b border-border ${f.width}`}
                  >
                    {f.label}
                  </th>
                ))}
                <th className="text-center font-semibold px-2 py-2 border-b border-border w-[70px]">
                  Delete
                </th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((row) => (
                <tr
                  key={row.id}
                  className={`border-b border-border ${
                    row._delete
                      ? "bg-destructive/10 line-through opacity-70"
                      : row._dirty
                      ? "bg-amber-50 dark:bg-amber-950/20"
                      : "hover:bg-muted/50"
                  }`}
                >
                  {FIELDS.map((f) => {
                    const val: any = (row as any)[f.key];
                    return (
                      <td key={f.key as string} className="px-2 py-1 align-top">
                        {f.type === "checkbox" ? (
                          <div className="flex items-center justify-center pt-2">
                            <Checkbox
                              checked={!!val}
                              disabled={row._delete}
                              onCheckedChange={(c) => updateCell(row.id, f.key, !!c)}
                            />
                          </div>
                        ) : f.type === "textarea" ? (
                          <Textarea
                            value={val || ""}
                            disabled={row._delete}
                            onChange={(e) => updateCell(row.id, f.key, e.target.value)}
                            rows={2}
                            className="text-sm min-h-[40px]"
                          />
                        ) : (
                          <Input
                            value={val || ""}
                            disabled={row._delete}
                            onChange={(e) => updateCell(row.id, f.key, e.target.value)}
                            className="h-8 text-sm"
                          />
                        )}
                      </td>
                    );
                  })}
                  <td className="px-2 py-1 align-top">
                    <div className="flex items-center justify-center pt-2">
                      <Checkbox
                        checked={!!row._delete}
                        onCheckedChange={(c) => toggleDelete(row.id, !!c)}
                        aria-label={`Mark ${row.name} for deletion`}
                      />
                    </div>
                  </td>
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr>
                  <td colSpan={FIELDS.length + 1} className="text-center text-muted-foreground py-8">
                    No vendors match your search.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>

        <DialogFooter className="pt-2">
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
            Cancel
          </Button>
          <Button
            onClick={handleSave}
            disabled={saving || totalChanges === 0}
            variant={deleteCount > 0 && dirtyCount === 0 ? "destructive" : "default"}
          >
            {saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            {deleteCount > 0 && <Trash2 className="mr-2 h-4 w-4" />}
            Save Changes{totalChanges > 0 ? ` (${totalChanges})` : ""}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>

    <AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Delete {deleteCount} vendor{deleteCount === 1 ? "" : "s"}?</AlertDialogTitle>
          <AlertDialogDescription>
            This will permanently remove {deleteCount} vendor{deleteCount === 1 ? "" : "s"} from your records.
            Vendors that are referenced by existing bills or invoices cannot be deleted — consider marking them inactive instead.
            {dirtyCount > 0 && ` ${dirtyCount} edited row${dirtyCount === 1 ? "" : "s"} will also be saved.`}
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel disabled={saving}>Cancel</AlertDialogCancel>
          <AlertDialogAction
            onClick={(e) => {
              e.preventDefault();
              performSave();
            }}
            disabled={saving}
            className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
          >
            {saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            Delete & Save
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
    </>
  );
}
