import { useState } from "react";
import { Button } from "@/components/ui/button";
import { FileDown, Loader2 } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import jsPDF from "jspdf";
import { format } from "date-fns";

interface BoardVotePdfExportProps {
  vote: {
    id: string;
    title: string;
    description?: string | null;
    status: string;
    created_at: string;
    vote_options?: string[] | null;
    associations?: { name: string } | null;
  };
}

export default function BoardVotePdfExport({ vote }: BoardVotePdfExportProps) {
  const [generating, setGenerating] = useState(false);
  const { toast } = useToast();

  const handleExport = async () => {
    setGenerating(true);
    try {
      // Fetch all responses for this board vote
      const { data: responses, error } = await supabase
        .from("board_vote_responses")
        .select("id, user_id, vote_option, created_at")
        .eq("board_vote_id", vote.id)
        .order("created_at", { ascending: true });

      if (error) throw error;

      const allResponses = responses ?? [];

      // Fetch profiles for voters
      const userIds = Array.from(new Set(allResponses.map((v) => v.user_id).filter(Boolean)));
      const profileMap = new Map<string, any>();
      if (userIds.length > 0) {
        const { data: profiles } = await supabase
          .from("profiles")
          .select("user_id, full_name, email")
          .in("user_id", userIds);
        (profiles ?? []).forEach((p) => profileMap.set(p.user_id, p));
      }

      // Group responses by option (preserve declared order, then append any extras)
      const declaredOptions = (vote.vote_options || []).map(String);
      const grouped = new Map<string, typeof allResponses>();
      declaredOptions.forEach((opt) => grouped.set(opt, []));
      allResponses.forEach((r) => {
        const key = String(r.vote_option ?? "(no response)");
        if (!grouped.has(key)) grouped.set(key, []);
        grouped.get(key)!.push(r);
      });

      const associationName = vote.associations?.name || "N/A";

      const doc = new jsPDF({ orientation: "portrait", unit: "pt", format: "letter" });
      const pageW = doc.internal.pageSize.getWidth();
      const pageH = doc.internal.pageSize.getHeight();
      const margin = 50;
      const contentW = pageW - margin * 2;
      let y = margin;

      const ensureSpace = (needed: number) => {
        if (y + needed > pageH - 60) {
          doc.addPage();
          y = margin;
        }
      };

      // Header bar
      doc.setFillColor(30, 41, 59);
      doc.rect(0, 0, pageW, 80, "F");
      doc.setTextColor(255, 255, 255);
      doc.setFontSize(22);
      doc.setFont("helvetica", "bold");
      doc.text("BOARD VOTE RECORD", margin, 50);
      doc.setFontSize(10);
      doc.setFont("helvetica", "normal");
      doc.text("Official Record of Board Action", margin, 68);

      y = 110;

      // Vote details
      doc.setTextColor(100, 116, 139);
      doc.setFontSize(9);
      doc.text("VOTE DETAILS", margin, y);
      y += 6;
      doc.setDrawColor(226, 232, 240);
      doc.setLineWidth(0.5);
      doc.line(margin, y, margin + contentW, y);
      y += 20;

      doc.setTextColor(30, 41, 59);
      const tallySummary = Array.from(grouped.entries())
        .map(([opt, rs]) => `${opt}: ${rs.length}`)
        .join("   |   ");

      const details: [string, string][] = [
        ["Title", vote.title],
        ["Association", associationName],
        ["Status", vote.status.charAt(0).toUpperCase() + vote.status.slice(1)],
        ["Date Created", format(new Date(vote.created_at), "MMMM d, yyyy")],
        ["Total Votes Cast", String(allResponses.length)],
        ["Tally", tallySummary || "—"],
      ];

      details.forEach(([label, value]) => {
        doc.setFont("helvetica", "bold");
        doc.setFontSize(10);
        doc.text(label + ":", margin, y);
        doc.setFont("helvetica", "normal");
        const lines = doc.splitTextToSize(value, contentW - 120);
        doc.text(lines, margin + 120, y);
        y += 14 * Math.max(lines.length, 1) + 4;
      });

      y += 6;

      // Description
      if (vote.description) {
        ensureSpace(60);
        doc.setTextColor(100, 116, 139);
        doc.setFontSize(9);
        doc.text("DESCRIPTION", margin, y);
        y += 6;
        doc.line(margin, y, margin + contentW, y);
        y += 16;
        doc.setTextColor(30, 41, 59);
        doc.setFontSize(10);
        doc.setFont("helvetica", "normal");
        const descLines = doc.splitTextToSize(vote.description, contentW);
        doc.text(descLines, margin, y);
        y += descLines.length * 14 + 10;
      }

      // Result banner — winning option(s)
      const counts = Array.from(grouped.entries()).map(([opt, rs]) => [opt, rs.length] as const);
      const maxCount = counts.reduce((m, [, c]) => Math.max(m, c), 0);
      const winners = counts.filter(([, c]) => c === maxCount && maxCount > 0).map(([o]) => o);
      let resultLabel: string;
      let bannerColor: number[];
      if (allResponses.length === 0) {
        resultLabel = "NO VOTES RECORDED";
        bannerColor = [100, 116, 139];
      } else if (winners.length > 1) {
        resultLabel = `TIE: ${winners.join(" / ")}`;
        bannerColor = [202, 138, 4];
      } else {
        resultLabel = `RESULT: ${winners[0]?.toUpperCase()}`;
        const w = (winners[0] || "").toLowerCase();
        bannerColor = ["approve", "yes", "for", "aye"].includes(w)
          ? [22, 163, 74]
          : ["deny", "no", "against", "nay"].includes(w)
          ? [220, 38, 38]
          : [37, 99, 235];
      }

      ensureSpace(50);
      doc.setFillColor(bannerColor[0], bannerColor[1], bannerColor[2]);
      doc.roundedRect(margin, y, contentW, 36, 4, 4, "F");
      doc.setTextColor(255, 255, 255);
      doc.setFontSize(14);
      doc.setFont("helvetica", "bold");
      doc.text(resultLabel, margin + 16, y + 24);
      y += 56;

      // Per-option voter tables
      const orderedKeys = [
        ...declaredOptions.filter((o) => grouped.has(o)),
        ...Array.from(grouped.keys()).filter((k) => !declaredOptions.includes(k)),
      ];

      orderedKeys.forEach((opt) => {
        const rs = grouped.get(opt) || [];
        if (rs.length === 0) return;

        ensureSpace(60);
        doc.setTextColor(100, 116, 139);
        doc.setFontSize(9);
        doc.setFont("helvetica", "normal");
        doc.text(`MEMBERS WHO VOTED "${opt.toUpperCase()}" (${rs.length})`, margin, y);
        y += 6;
        doc.line(margin, y, margin + contentW, y);
        y += 8;

        // Table header
        doc.setFillColor(241, 245, 249);
        doc.rect(margin, y, contentW, 22, "F");
        doc.setTextColor(71, 85, 105);
        doc.setFontSize(9);
        doc.setFont("helvetica", "bold");
        doc.text("#", margin + 8, y + 15);
        doc.text("Name", margin + 40, y + 15);
        doc.text("Email", margin + 240, y + 15);
        doc.text("Date", margin + 420, y + 15);
        y += 22;

        doc.setFont("helvetica", "normal");
        doc.setTextColor(30, 41, 59);
        rs.forEach((v, i) => {
          ensureSpace(22);
          const profile = profileMap.get(v.user_id);
          const name = profile?.full_name || "Unknown";
          const email = profile?.email || "—";
          const dateStr = format(new Date(v.created_at), "M/d/yyyy h:mm a");

          if (i % 2 === 0) {
            doc.setFillColor(248, 250, 252);
            doc.rect(margin, y - 4, contentW, 20, "F");
          }

          doc.setFontSize(9);
          doc.text(String(i + 1), margin + 8, y + 10);
          doc.text(doc.splitTextToSize(name, 190)[0], margin + 40, y + 10);
          doc.text(doc.splitTextToSize(email, 170)[0], margin + 240, y + 10);
          doc.text(dateStr, margin + 420, y + 10);
          y += 20;
        });
        y += 12;
      });

      // Footer on every page
      const totalPages = (doc as any).internal.getNumberOfPages();
      for (let i = 1; i <= totalPages; i++) {
        doc.setPage(i);
        const footerY = pageH - 40;
        doc.setDrawColor(226, 232, 240);
        doc.line(margin, footerY, margin + contentW, footerY);
        doc.setTextColor(148, 163, 184);
        doc.setFontSize(8);
        doc.text(`Generated on ${format(new Date(), "MMMM d, yyyy 'at' h:mm a")}`, margin, footerY + 14);
        doc.text(`Page ${i} of ${totalPages}`, margin + contentW - 60, footerY + 14);
      }

      const safeName = vote.title.replace(/[^a-z0-9]/gi, "_").substring(0, 40);
      doc.save(`Board_Vote_${safeName}_${format(new Date(), "yyyy-MM-dd")}.pdf`);
      toast({ title: "PDF exported successfully" });
    } catch (err: any) {
      console.error("PDF export error:", err);
      toast({ variant: "destructive", title: "Export failed", description: err.message });
    } finally {
      setGenerating(false);
    }
  };

  return (
    <Button variant="outline" size="sm" onClick={handleExport} disabled={generating} className="gap-2">
      {generating ? <Loader2 className="h-4 w-4 animate-spin" /> : <FileDown className="h-4 w-4" />}
      {generating ? "Generating..." : "Export PDF"}
    </Button>
  );
}
