import { useEffect, useMemo, useState } from "react";
import ImportSpreadsheetDialog from "@/components/ImportSpreadsheetDialog";
import { supabase } from "@/integrations/supabase/client";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import { Download, Upload, Briefcase } from "lucide-react";

const PAGE_SIZE = 1000;

const normalize = (value: string | null | undefined) =>
  String(value ?? "").trim().replace(/\s+/g, " ").toLowerCase();

const nullable = (value: string | null | undefined) => {
  const trimmed = String(value ?? "").trim();
  return trimmed ? trimmed : null;
};

const parseBool = (value: string | null | undefined): boolean | null => {
  const v = normalize(value);
  if (!v) return null;
  if (["true", "yes", "y", "1"].includes(v)) return true;
  if (["false", "no", "n", "0"].includes(v)) return false;
  return null;
};

interface VendorLookup {
  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;
  is_active: boolean;
}

export default function BulkVendorUpdatesTab() {
  const { toast } = useToast();
  const [vendors, setVendors] = useState<VendorLookup[]>([]);
  const [loading, setLoading] = useState(false);
  const [importOpen, setImportOpen] = useState(false);
  const [lastResult, setLastResult] = useState<{ updated: number; skipped: number } | null>(null);

  useEffect(() => { fetchVendors(); }, []);

  const fetchVendors = async () => {
    setLoading(true);
    const all: VendorLookup[] = [];
    for (let from = 0; ; from += PAGE_SIZE) {
      const { data, error } = await supabase
        .from("vendors")
        .select("id, name, contact_name, email, phone, address, tax_id, payment_terms, is_1099_eligible, is_active")
        .order("name")
        .range(from, from + PAGE_SIZE - 1);
      if (error) {
        toast({ title: "Error loading vendors", description: error.message, variant: "destructive" });
        break;
      }
      if (!data?.length) break;
      // De-duplicate by id (vendors can appear multiple times across association_ids)
      const seen = new Set(all.map(v => v.id));
      data.forEach((v) => { if (!seen.has(v.id)) all.push(v as VendorLookup); });
      if (data.length < PAGE_SIZE) break;
    }
    setVendors(all);
    setLoading(false);
  };

  const lookupMaps = useMemo(() => {
    const byId = new Map<string, string>();
    const byName = new Map<string, string>();
    const byTaxId = new Map<string, string>();
    const byEmail = new Map<string, string>();
    vendors.forEach((v) => {
      byId.set(v.id, v.id);
      if (v.name) byName.set(normalize(v.name), v.id);
      if (v.tax_id) byTaxId.set(normalize(v.tax_id), v.id);
      if (v.email) byEmail.set(normalize(v.email), v.id);
    });
    return { byId, byName, byTaxId, byEmail };
  }, [vendors]);

  const handleImportUpdates = async (rows: Record<string, string>[]) => {
    const updates: Array<{ id: string; payload: Record<string, unknown> }> = [];
    let skipped = 0;

    rows.forEach((row) => {
      const id = nullable(row.vendor_id);
      const matchedId =
        (id && lookupMaps.byId.get(id)) ||
        (nullable(row.vendor_name) && lookupMaps.byName.get(normalize(row.vendor_name))) ||
        (nullable(row.tax_id) && lookupMaps.byTaxId.get(normalize(row.tax_id))) ||
        (nullable(row.email) && lookupMaps.byEmail.get(normalize(row.email)));

      if (!matchedId) { skipped += 1; return; }

      const payload: Record<string, unknown> = { updated_at: new Date().toISOString() };
      const newName = nullable(row.new_vendor_name);
      if (newName) payload.name = newName;

      ["contact_name", "email", "phone", "address", "tax_id", "payment_terms", "notes", "zoho_contact_id"].forEach((field) => {
        const value = nullable(row[field]);
        if (value !== null) payload[field] = value;
      });

      const is1099 = parseBool(row.is_1099_eligible);
      if (is1099 !== null) payload.is_1099_eligible = is1099;

      const active = parseBool(row.is_active);
      if (active !== null) payload.is_active = active;

      if (Object.keys(payload).length > 1) updates.push({ id: matchedId, payload });
      else skipped += 1;
    });

    for (let i = 0; i < updates.length; i += 25) {
      const results = await Promise.all(updates.slice(i, i + 25).map(({ id, payload }) => supabase.from("vendors").update(payload).eq("id", id)));
      const failed = results.find((result) => result.error);
      if (failed?.error) throw failed.error;
    }

    setLastResult({ updated: updates.length, skipped });
    toast({ title: "Bulk update complete", description: `${updates.length} vendors updated, ${skipped} rows skipped.` });
    await fetchVendors();
  };

  const handleExportTemplate = async () => {
    const csv = [
      "Vendor ID,Vendor Name,New Vendor Name,Contact Name,Email,Phone,Address,Tax ID,Payment Terms,Is 1099 Eligible,Is Active,Notes,Zoho Contact ID",
      ...vendors.map((v) => [
        v.id,
        v.name || "",
        "",
        v.contact_name || "",
        v.email || "",
        v.phone || "",
        v.address || "",
        v.tax_id || "",
        v.payment_terms || "",
        v.is_1099_eligible ? "true" : "false",
        v.is_active ? "true" : "false",
        "", "",
      ].map((value) => `"${String(value).replace(/"/g, '""')}"`).join(",")),
    ].join("\n");
    const { saveFile } = await import("@/lib/saveFile");
    await saveFile(new Blob([csv], { type: "text/csv" }), { suggestedName: "bulk_vendor_updates.csv", mimeType: "text/csv", description: "CSV file" });
  };

  return (
    <div className="space-y-6">
      <p className="text-sm text-muted-foreground">Update vendor contact info, payment terms, tax ID, and active status from a spreadsheet without creating new vendor records.</p>

      <Card>
        <CardHeader><CardTitle>Update Spreadsheet</CardTitle></CardHeader>
        <CardContent className="space-y-4">
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" className="gap-2" onClick={handleExportTemplate} disabled={!vendors.length}><Download className="h-4 w-4" /> Export Update Template</Button>
            <Button className="gap-2" onClick={() => setImportOpen(true)}><Upload className="h-4 w-4" /> Import Updates</Button>
          </div>
          {lastResult && <Badge variant="secondary">Last import: {lastResult.updated} updated, {lastResult.skipped} skipped</Badge>}
        </CardContent>
      </Card>

      <Card>
        <CardHeader><CardTitle className="flex items-center gap-2"><Briefcase className="h-5 w-5" /> Current Vendors ({vendors.length})</CardTitle></CardHeader>
        <CardContent>
          <div className="rounded-md border border-border overflow-x-auto">
            <Table>
              <TableHeader><TableRow><TableHead>Vendor</TableHead><TableHead>Contact</TableHead><TableHead>Email</TableHead><TableHead>Phone</TableHead><TableHead>Tax ID</TableHead><TableHead>1099</TableHead><TableHead>Active</TableHead></TableRow></TableHeader>
              <TableBody>
                {loading ? <TableRow><TableCell colSpan={7} className="text-center text-muted-foreground py-8">Loading vendors...</TableCell></TableRow> : vendors.slice(0, 50).map((v) => (
                  <TableRow key={v.id}>
                    <TableCell className="font-medium">{v.name}</TableCell>
                    <TableCell>{v.contact_name || "—"}</TableCell>
                    <TableCell>{v.email || "—"}</TableCell>
                    <TableCell>{v.phone || "—"}</TableCell>
                    <TableCell>{v.tax_id || "—"}</TableCell>
                    <TableCell>{v.is_1099_eligible ? "Yes" : "No"}</TableCell>
                    <TableCell>{v.is_active ? "Yes" : "No"}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
            {vendors.length > 50 && <p className="text-xs text-muted-foreground p-2">Showing first 50 of {vendors.length} vendors.</p>}
          </div>
        </CardContent>
      </Card>

      <ImportSpreadsheetDialog
        open={importOpen}
        onOpenChange={setImportOpen}
        title="Import Vendor Updates"
        description="Rows are matched by Vendor ID first, then Vendor Name, Tax ID, or Email. Blank update fields are ignored."
        templateFileName="bulk_vendor_updates_template.xlsx"
        expectedColumns={[
          { key: "vendor_id", label: "Vendor ID", aliases: ["ID"] },
          { key: "vendor_name", label: "Vendor Name", required: true, aliases: ["Vendor", "Name"] },
          { key: "new_vendor_name", label: "New Vendor Name" },
          { key: "contact_name", label: "Contact Name", aliases: ["Contact"] },
          { key: "email", label: "Email" },
          { key: "phone", label: "Phone" },
          { key: "address", label: "Address" },
          { key: "tax_id", label: "Tax ID", aliases: ["EIN", "SSN"] },
          { key: "payment_terms", label: "Payment Terms", aliases: ["Terms"] },
          { key: "is_1099_eligible", label: "Is 1099 Eligible", aliases: ["1099"] },
          { key: "is_active", label: "Is Active", aliases: ["Active"] },
          { key: "notes", label: "Notes" },
          { key: "zoho_contact_id", label: "Zoho Contact ID" },
        ]}
        onImport={handleImportUpdates}
      />
    </div>
  );
}
