import { useState, useEffect, useRef, useCallback } from "react";
import { PDFDocument } from "pdf-lib";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import {
  ArrowRight, ArrowLeft, Download, FileText,
  Layout, Eye, Printer, Loader2, CheckSquare, Plus, Trash2, GripVertical, Paperclip,
} from "lucide-react";
import { jsPDF } from "jspdf";
import autoTable from "jspdf-autotable";
import { drawReportCoverPage } from "@/lib/reportCover";
import { format, subMonths } from "date-fns";
import type { Tables } from "@/integrations/supabase/types";
import { ensureFontsLoaded } from "@/lib/googleFontsManager";
import { loadFontForPdf, registerFontWithJsPdf } from "@/lib/fontPdfLoader";
import {
  DragDropContext,
  Droppable,
  Draggable,
  type DropResult,
} from "@hello-pangea/dnd";

// ─── Strict-mode-safe Droppable wrapper ───
function StrictModeDroppable({ children, ...props }: React.ComponentProps<typeof Droppable>) {
  const [enabled, setEnabled] = useState(false);
  useEffect(() => {
    const id = requestAnimationFrame(() => setEnabled(true));
    return () => { cancelAnimationFrame(id); setEnabled(false); };
  }, []);
  if (!enabled) return null;
  return <Droppable {...props}>{children}</Droppable>;
}

interface CoverData {
  title: string;
  date: string;
  companyName: string;
  preparedBy: string;
  logoUrl: string;
  bgUrl: string;
}

/** A single entry in the unified report order list */
interface ReportEntry {
  id: string;
  type: "module" | "attachment";
  /** For module type: the DATA_MODULES key. For attachment: undefined */
  moduleKey?: string;
  label: string;
  /** For attachment type: how many pages this attachment occupies */
  pageCount: number;
  enabled: boolean;
  /** For attachment type: the uploaded PDF file */
  file?: File;
  /** AI-generated summary for attachment PDFs */
  aiSummary?: string;
  /** Whether AI summary is being generated */
  summarizing?: boolean;
}

const DATA_MODULES = [
  { key: "statusUpdates", label: "Status Updates", table: "status_updates", dateCol: "created_at",
    columns: ["Date", "Title", "Content"], fields: ["created_at", "title", "content"] },
  { key: "ownerUpdates", label: "Owner Updates", table: "owner_updates", dateCol: "posted_at",
    columns: ["Date", "Property", "Title", "Content"], fields: ["posted_at", "_property", "title", "content"],
    customSelect: "*, units(unit_number, address)" },
  { key: "violations", label: "Violations", table: "violations", dateCol: "created_at",
    columns: ["Date", "Address", "Type", "Status", "Stage"], fields: ["created_at", "address", "violation_type", "status", "stage"] },
  { key: "collections", label: "Collections", table: "collections", dateCol: "updated_at",
    columns: ["Property", "Owner", "Amount Owed", "Status", "Last Notice"], fields: ["_property", "_owner_name", "amount_owed", "status", "last_notice_date"],
    noDateFilter: true, customSelect: "*, units(unit_number, address), owners(first_name, last_name)" },
  { key: "legalMatters", label: "Legal Cases", table: "legal_matters", dateCol: "created_at",
    columns: ["Case #", "Title", "Category", "Stage", "Status"], fields: ["case_number", "title", "category", "stage", "status"], noDateFilter: true },
  { key: "arcApplications", label: "ARC Applications", table: "arc_applications", dateCol: "created_at",
    columns: ["Date", "Title", "Type", "Status"], fields: ["created_at", "title", "project_type", "status"] },
  { key: "boardVotes", label: "Board Votes", table: "board_votes", dateCol: "created_at",
    columns: ["Date", "Title", "Status"], fields: ["created_at", "title", "status"] },
  { key: "estoppels", label: "Estoppels", table: "estoppels", dateCol: "created_at",
    columns: ["Date", "Address", "Status", "Notes"], fields: ["created_at", "address", "status", "notes"] },
  { key: "homeownerRequests", label: "Homeowner Requests", table: "homeowner_requests", dateCol: "created_at",
    columns: ["Date", "Subject", "Status"], fields: ["created_at", "subject", "status"], noDateFilter: true },
  { key: "bidsQuotes", label: "Bids & Quotes", table: "bids_quotes", dateCol: "created_at",
    columns: ["Date", "Vendor", "Amount", "Status"], fields: ["created_at", "vendor_name", "amount", "status"] },
  { key: "callLogs", label: "Call Logs", table: "call_logs", dateCol: "created_at",
    columns: ["Date", "Caller", "Type", "Notes"], fields: ["created_at", "caller_name", "call_type", "notes"] },
] as const;

type ModuleKey = typeof DATA_MODULES[number]["key"];

export default function ReportGeneratorPage() {
  const { toast } = useToast();
  const [associations, setAssociations] = useState<Tables<"associations">[]>([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState("");
  const [startDate, setStartDate] = useState(format(subMonths(new Date(), 1), "yyyy-MM-dd"));
  const [endDate, setEndDate] = useState(format(new Date(), "yyyy-MM-dd"));

  const [step, setStep] = useState(1);
  const [isExporting, setIsExporting] = useState(false);
  const [dataLoading, setDataLoading] = useState(false);
  const [reportData, setReportData] = useState<Record<string, any[]>>({});
  const previewRef = useRef<HTMLDivElement>(null);
  

  const [coverData, setCoverData] = useState<CoverData>({
    title: "MANAGEMENT\nREPORT",
    date: format(new Date(), "MMMM yyyy"),
    companyName: "",
    preparedBy: "Avria Community Management, LLC",
    logoUrl: "",
    bgUrl: "",
  });

  // Unified ordered list of report entries
  const [reportEntries, setReportEntries] = useState<ReportEntry[]>(() =>
    DATA_MODULES.map((m) => ({
      id: m.key,
      type: "module" as const,
      moduleKey: m.key,
      label: m.label,
      pageCount: 1,
      enabled: true,
    }))
  );

  // Attachment add form
  const [newAttLabel, setNewAttLabel] = useState("");
  const [newAttPages, setNewAttPages] = useState("1");
  const [newAttFile, setNewAttFile] = useState<File | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    supabase.from("associations").select("*").eq("status", "active").order("name").then(({ data }) => {
      setAssociations(data || []);
    });
  }, []);

  useEffect(() => {
    const assoc = associations.find((a) => a.id === selectedAssociationId);
    if (assoc) {
      setCoverData((prev) => ({ ...prev, companyName: assoc.name, logoUrl: assoc.logo_url || "" }));
    }
  }, [selectedAssociationId, associations]);

  const fetchReportData = useCallback(async () => {
    if (!selectedAssociationId) return;
    setDataLoading(true);
    const result: Record<string, any[]> = {};
    const sd = startDate;
    const ed = endDate + "T23:59:59";

    const enabledModuleKeys = reportEntries.filter((e) => e.type === "module" && e.enabled).map((e) => e.moduleKey!);
    const enabledList = DATA_MODULES.filter((m) => enabledModuleKeys.includes(m.key));

    await Promise.all(
      enabledList.map(async (mod) => {
        try {
          const selectStr = (mod as any).customSelect || "*";
          let query = supabase
            .from(mod.table as any)
            .select(selectStr)
            .eq("association_id", selectedAssociationId)
            .order(mod.dateCol, { ascending: false });

          if (!("noDateFilter" in mod && mod.noDateFilter)) {
            query = query.gte(mod.dateCol, sd).lte(mod.dateCol, ed);
          }

          const { data } = await query;
          if (mod.key === "collections" && data) {
            result[mod.key] = data.map((row: any) => ({
              ...row,
              _property: row.units?.address || row.units?.unit_number || "-",
              _owner_name: row.owners ? `${row.owners.first_name || ""} ${row.owners.last_name || ""}`.trim() : "-",
            }));
          } else if (mod.key === "ownerUpdates" && data) {
            result[mod.key] = data.map((row: any) => ({
              ...row,
              _property: row.units?.address || row.units?.unit_number || "-",
            }));
          } else {
            result[mod.key] = data || [];
          }
        } catch {
          result[mod.key] = [];
        }
      })
    );

    setReportData(result);
    setDataLoading(false);
  }, [selectedAssociationId, startDate, endDate, reportEntries]);

  const handleCoverChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    setCoverData((prev) => ({ ...prev, [e.target.name]: e.target.value }));
  };

  const toggleEntry = (id: string) => {
    setReportEntries((prev) => prev.map((e) => e.id === id ? { ...e, enabled: !e.enabled } : e));
  };

  const removeEntry = (id: string) => {
    setReportEntries((prev) => prev.filter((e) => e.id !== id));
  };

  const addAttachment = () => {
    if (!newAttLabel.trim()) return;
    const pc = Math.max(1, parseInt(newAttPages) || 1);
    const entryId = crypto.randomUUID();
    const file = newAttFile || undefined;
    setReportEntries((prev) => [
      ...prev,
      { id: entryId, type: "attachment", label: newAttLabel.trim(), pageCount: pc, enabled: true, file, summarizing: !!file },
    ]);
    setNewAttLabel("");
    setNewAttPages("1");
    setNewAttFile(null);
    if (fileInputRef.current) fileInputRef.current.value = "";

    // Trigger AI summary generation in the background
    if (file) {
      generateAttachmentSummary(entryId, file, newAttLabel.trim());
    }
  };

  const generateAttachmentSummary = async (entryId: string, file: File, label: string) => {
    try {
      // Upload temporarily to get a URL for the summarizer
      const tempPath = `temp-report-summaries/${entryId}.pdf`;
      const { error: uploadError } = await supabase.storage
        .from("files")
        .upload(tempPath, file, { upsert: true });
      if (uploadError) throw uploadError;

      const { data: urlData } = await supabase.storage
        .from("files")
        .createSignedUrl(tempPath, 300); // 5 min expiry

      if (!urlData?.signedUrl) throw new Error("Failed to get signed URL");

      const { data, error } = await supabase.functions.invoke("summarize-document", {
        body: { documentId: entryId, fileUrl: urlData.signedUrl, title: label },
      });

      if (error) throw error;

      setReportEntries((prev) =>
        prev.map((e) => e.id === entryId ? { ...e, aiSummary: data?.summary || undefined, summarizing: false } : e)
      );

      // Clean up temp file
      await supabase.storage.from("files").remove([tempPath]);

      if (data?.summary) {
        toast({ title: "AI Summary Generated", description: `Summary ready for "${label}"` });
      }
    } catch (err) {
      console.error("Attachment summary failed:", err);
      setReportEntries((prev) =>
        prev.map((e) => e.id === entryId ? { ...e, summarizing: false } : e)
      );
    }
  };

  const handleAttachmentFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (file.type !== "application/pdf") {
      toast({ variant: "destructive", title: "Invalid File", description: "Only PDF files are supported." });
      e.target.value = "";
      return;
    }
    setNewAttFile(file);
    // Auto-detect page count
    try {
      const buffer = await file.arrayBuffer();
      const pdfDoc = await PDFDocument.load(buffer);
      setNewAttPages(String(pdfDoc.getPageCount()));
    } catch {
      // Keep manual page count if detection fails
    }
    // Auto-fill label from filename if empty
    if (!newAttLabel.trim()) {
      setNewAttLabel(file.name.replace(/\.pdf$/i, ""));
    }
  };

  const onDragEnd = (result: DropResult) => {
    if (!result.destination) return;
    const items = Array.from(reportEntries);
    const [moved] = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, moved);
    setReportEntries(items);
  };

  /** Compute page number for each enabled entry. Cover=1, TOC=2, content starts at 3. */
  const computePageNumbers = useCallback((): Map<string, number> => {
    const map = new Map<string, number>();
    let page = 3; // cover=1, TOC=2
    for (const entry of reportEntries) {
      if (!entry.enabled) continue;
      map.set(entry.id, page);
      if (entry.type === "attachment") {
        page += entry.pageCount;
      } else {
        const rows = reportData[entry.moduleKey!]?.length || 0;
        page += Math.max(1, Math.ceil(rows / 30));
      }
    }
    return map;
  }, [reportEntries, reportData]);

  const pageNumbers = computePageNumbers();

  const handlePrint = () => {
    if (!previewRef.current) return;
    const printWindow = window.open("", "_blank");
    if (!printWindow) return;
    printWindow.document.write(`<html><head><title>${coverData.title.replace(/\n/g, " ")}</title><style>body{margin:0;font-family:sans-serif}table{border-collapse:collapse;width:100%}th,td{border:1px solid #e2e8f0;padding:6px 8px;font-size:10px;text-align:left}th{background:#1e293b;color:#fff}.print-page{page-break-after:always}</style></head><body>${previewRef.current.innerHTML}</body></html>`);
    printWindow.document.close();
    printWindow.focus();
    printWindow.print();
    printWindow.close();
  };

  const cleanText = (text: string) => {
    if (!text) return "-";
    return text.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").trim() || "-";
  };

  const formatDate = (d: string) => {
    if (!d) return "-";
    try { return format(new Date(d), "MM/dd/yyyy"); } catch { return "-"; }
  };

  const formatCurrency = (v: any) => {
    const n = parseFloat(v);
    if (isNaN(n)) return "-";
    return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(n);
  };

  const getCellValue = (row: any, field: string) => {
    const val = row[field];
    if (val === null || val === undefined) return "-";
    if (field.includes("date") || field === "created_at" || field === "updated_at" || field === "posted_at") return formatDate(val);
    if (field === "amount" || field === "amount_due" || field === "amount_owed") return formatCurrency(val);
    if (field === "content") return cleanText(String(val)).slice(0, 120);
    return cleanText(String(val));
  };

  /** Only enabled entries that are modules with data, in order */
  const getOrderedActiveModules = () => {
    return reportEntries
      .filter((e) => e.enabled && e.type === "module" && reportData[e.moduleKey!]?.length > 0)
      .map((e) => ({ ...DATA_MODULES.find((m) => m.key === e.moduleKey)!, entryId: e.id }));
  };

  /** All enabled entries (modules with data + attachments) in order */
  const getOrderedEnabledEntries = () => {
    return reportEntries.filter((e) => {
      if (!e.enabled) return false;
      if (e.type === "attachment") return true;
      return reportData[e.moduleKey!]?.length > 0;
    });
  };

  // ── PDF Generation ──
  const generatePDF = async () => {
    setIsExporting(true);
    toast({ title: "Generating PDF…", description: "Please wait." });
    try {
      await ensureFontsLoaded(["Open Sans"]);

      const doc = new jsPDF({ orientation: "portrait", unit: "pt", format: "letter" });
      const openSansRegular = await loadFontForPdf("Open Sans", "Regular");
      const openSansBold = await loadFontForPdf("Open Sans", "Bold");
      registerFontWithJsPdf(doc, "Open Sans", openSansRegular, "normal");
      registerFontWithJsPdf(doc, "Open Sans", openSansBold, "bold");

      const W = doc.internal.pageSize.getWidth();
      const H = doc.internal.pageSize.getHeight();
      const M = 40;
      const cx = W / 2;
      const pdfFont = openSansRegular ? "Open Sans" : "helvetica";

      const drawPageFooter = (pageNum: number) => {
        doc.setFont(pdfFont, "normal");
        doc.setFontSize(8);
        doc.setTextColor(148, 163, 184);
        doc.text(`${coverData.companyName} — ${coverData.date}`, M, H - 20);
        doc.text(`Page ${pageNum}`, W - M, H - 20, { align: "right" });
        doc.setDrawColor(226, 232, 240);
        doc.setLineWidth(0.5);
        doc.line(M, H - 30, W - M, H - 30);
      };

      // ═══ COVER PAGE ═══
      await drawReportCoverPage(doc, W, H, coverData);

      const orderedEntries = getOrderedEnabledEntries();

      // ═══ TABLE OF CONTENTS ═══
      if (orderedEntries.length > 0) {
        doc.addPage();
        let pageNum = 2;
        drawPageFooter(pageNum);

        let y = 60;
        doc.setFillColor(30, 41, 59);
        doc.rect(M, y - 20, 4, 28, "F");
        doc.setFont("helvetica", "bold");
        doc.setFontSize(24);
        doc.setTextColor(15, 23, 42);
        doc.text("TABLE OF CONTENTS", M + 16, y);
        y += 12;
        doc.setDrawColor(30, 41, 59);
        doc.setLineWidth(2);
        doc.line(M, y, W - M, y);
        y += 8;
        doc.setDrawColor(226, 232, 240);
        doc.setLineWidth(0.5);
        doc.line(M, y, W - M, y);
        y += 30;

        orderedEntries.forEach((entry, idx) => {
          if (y > H - 80) {
            doc.addPage(); pageNum++; drawPageFooter(pageNum); y = 60;
          }

          const sectionNum = String(idx + 1).padStart(2, "0");
          const pg = String(pageNumbers.get(entry.id) || "");
          const isAtt = entry.type === "attachment";

          doc.setFont("helvetica", "bold");
          doc.setFontSize(11);
          doc.setTextColor(30, 41, 59);
          doc.text(sectionNum, M + 4, y);

          doc.setFont("helvetica", "normal");
          doc.setFontSize(12);
          doc.setTextColor(51, 65, 85);
          doc.text(entry.label, M + 36, y);

          const titleEndX = M + 36 + doc.getTextWidth(entry.label) + 8;
          const pageNumX = W - M - doc.getTextWidth(pg) - 4;
          doc.setFontSize(10);
          doc.setTextColor(203, 213, 225);
          let dotX = titleEndX;
          while (dotX < pageNumX - 4) { doc.text(".", dotX, y); dotX += 5; }

          doc.setFont("helvetica", "bold");
          doc.setFontSize(12);
          doc.setTextColor(30, 41, 59);
          doc.text(pg, W - M, y, { align: "right" });

          if (!isAtt && entry.moduleKey) {
            doc.setFont("helvetica", "normal");
            doc.setFontSize(8);
            doc.setTextColor(148, 163, 184);
            doc.text(`${reportData[entry.moduleKey]?.length || 0} records`, M + 36, y + 12);
          } else {
            doc.setFont("helvetica", "normal");
            doc.setFontSize(8);
            doc.setTextColor(148, 163, 184);
            doc.text(`${entry.pageCount} page${entry.pageCount > 1 ? "s" : ""} (attachment)`, M + 36, y + 12);
          }

          y += 32;
          doc.setDrawColor(241, 245, 249);
          doc.setLineWidth(0.5);
          doc.line(M + 36, y - 10, W - M, y - 10);
        });
      }

      // ═══ DATA SECTION PAGES ═══
      const tableTheme = {
        headStyles: { fillColor: [30, 41, 59] as [number, number, number], textColor: 255, fontStyle: "bold" as const, fontSize: 9, cellPadding: 6 },
        bodyStyles: { textColor: [51, 65, 85] as [number, number, number], fontSize: 8, cellPadding: 5 },
        alternateRowStyles: { fillColor: [248, 250, 252] as [number, number, number] },
        styles: { lineColor: [226, 232, 240] as [number, number, number], lineWidth: 0.5, overflow: "linebreak" as const },
        margin: { top: 70, right: M, bottom: 50, left: M },
      };

      // Track which attachment files need to be merged and at which page position
      const attachmentMergeQueue: { file: File; afterPage: number }[] = [];

      let sectionIdx = 0;
      for (const entry of orderedEntries) {
        sectionIdx++;
        if (entry.type === "attachment") {
          if (entry.file) {
            // Add a section title page, then we'll merge actual PDF pages after jsPDF generation
            doc.addPage();
            let y = 50;
            doc.setFillColor(30, 41, 59);
            doc.roundedRect(M, y - 16, 36, 36, 4, 4, "F");
            doc.setFont("helvetica", "bold");
            doc.setFontSize(18);
            doc.setTextColor(255, 255, 255);
            doc.text(`${sectionIdx}`, M + 18, y + 6, { align: "center" });
            doc.setFontSize(20);
            doc.setTextColor(15, 23, 42);
            doc.text(entry.label, M + 48, y + 4);
            doc.setFontSize(10);
            doc.setTextColor(148, 163, 184);
            doc.text(`${entry.pageCount} page${entry.pageCount > 1 ? "s" : ""}`, W - M, y + 4, { align: "right" });
            y += 20;
            doc.setDrawColor(226, 232, 240);
            doc.setLineWidth(1);
            doc.line(M, y, W - M, y);

            // Render AI summary if available
            if (entry.aiSummary) {
              y += 24;
              doc.setFont("helvetica", "bold");
              doc.setFontSize(11);
              doc.setTextColor(30, 41, 59);
              doc.text("✦ Executive Summary", M, y);
              y += 16;
              doc.setFont("helvetica", "normal");
              doc.setFontSize(10);
              doc.setTextColor(71, 85, 105);
              const summaryLines = doc.splitTextToSize(entry.aiSummary, W - M * 2);
              doc.text(summaryLines, M, y);
              y += summaryLines.length * 14 + 8;
              doc.setDrawColor(226, 232, 240);
              doc.setLineWidth(0.5);
              doc.line(M, y, W - M, y);
            }

            drawPageFooter((doc as any).internal.getNumberOfPages());

            attachmentMergeQueue.push({
              file: entry.file,
              afterPage: (doc as any).internal.getNumberOfPages(),
            });
          } else {
            // No file — add blank placeholder pages
            for (let p = 0; p < entry.pageCount; p++) {
              doc.addPage();
              const pn = (doc as any).internal.getNumberOfPages();
              if (p === 0) {
                let y = 50;
                doc.setFillColor(30, 41, 59);
                doc.roundedRect(M, y - 16, 36, 36, 4, 4, "F");
                doc.setFont("helvetica", "bold");
                doc.setFontSize(18);
                doc.setTextColor(255, 255, 255);
                doc.text(`${sectionIdx}`, M + 18, y + 6, { align: "center" });
                doc.setFontSize(20);
                doc.setTextColor(15, 23, 42);
                doc.text(entry.label, M + 48, y + 4);
                doc.setFontSize(10);
                doc.setTextColor(148, 163, 184);
                doc.text("(attachment placeholder)", W - M, y + 4, { align: "right" });
                y += 20;
                doc.setDrawColor(226, 232, 240);
                doc.setLineWidth(1);
                doc.line(M, y, W - M, y);
              }
              drawPageFooter(pn);
            }
          }
          continue;
        }

        const mod = DATA_MODULES.find((m) => m.key === entry.moduleKey)!;
        doc.addPage();

        let y = 50;
        doc.setFillColor(30, 41, 59);
        doc.roundedRect(M, y - 16, 36, 36, 4, 4, "F");
        doc.setFont("helvetica", "bold");
        doc.setFontSize(18);
        doc.setTextColor(255, 255, 255);
        doc.text(`${sectionIdx}`, M + 18, y + 6, { align: "center" });
        doc.setFontSize(20);
        doc.setTextColor(15, 23, 42);
        doc.text(mod.label, M + 48, y + 4);
        doc.setFontSize(10);
        doc.setTextColor(148, 163, 184);
        doc.text(`${reportData[mod.key].length} records`, W - M, y + 4, { align: "right" });
        y += 20;
        doc.setDrawColor(226, 232, 240);
        doc.setLineWidth(1);
        doc.line(M, y, W - M, y);

        const rows = reportData[mod.key].map((row: any) => mod.fields.map((f) => getCellValue(row, f)));
        autoTable(doc, {
          startY: y + 10,
          head: [mod.columns as unknown as string[]],
          body: rows,
          ...tableTheme,
          didDrawPage: () => {
            const currentPage = (doc as any).internal.getNumberOfPages();
            drawPageFooter(currentPage);
          },
        });
      }

      // ═══ MERGE ATTACHMENT PDFs ═══
      if (attachmentMergeQueue.length > 0) {
        const jsPdfBytes = doc.output("arraybuffer");
        const jsPdfDoc = await PDFDocument.load(jsPdfBytes);

        // Create a brand new document and copy pages to avoid font corruption
        const mergedPdf = await PDFDocument.create();

        // Copy ALL jsPDF pages first
        const allJsPdfPages = await mergedPdf.copyPages(jsPdfDoc, jsPdfDoc.getPageIndices());
        allJsPdfPages.forEach((page) => mergedPdf.addPage(page));

        // Now insert attachment file pages at the correct positions
        // Process in reverse order so page indices stay correct
        for (let i = attachmentMergeQueue.length - 1; i >= 0; i--) {
          const { file, afterPage } = attachmentMergeQueue[i];
          try {
            const fileBuffer = await file.arrayBuffer();
            const attachPdf = await PDFDocument.load(fileBuffer);
            const copiedPages = await mergedPdf.copyPages(attachPdf, attachPdf.getPageIndices());
            // afterPage is 1-indexed, pdf-lib insertPage is 0-indexed
            copiedPages.forEach((page, idx) => {
              mergedPdf.insertPage(afterPage + idx, page);
            });
          } catch (e) {
            console.error(`Failed to merge attachment: ${file.name}`, e);
          }
        }

        const finalBytes = await mergedPdf.save();
        const blob = new Blob([new Uint8Array(finalBytes)], { type: "application/pdf" });
        const { saveFile } = await import("@/lib/saveFile");
        await saveFile(blob, {
          suggestedName: `Management_Report_${format(new Date(), "yyyy-MM-dd")}.pdf`,
          mimeType: "application/pdf",
          description: "PDF Document",
        });
      } else {
        doc.save(`Management_Report_${format(new Date(), "yyyy-MM-dd")}.pdf`);
      }
      toast({ title: "Success", description: "Report downloaded." });
    } catch (err) {
      console.error(err);
      toast({ variant: "destructive", title: "Export Failed", description: String(err) });
    } finally {
      setIsExporting(false);
    }
  };

  const goToStep = (newStep: number) => {
    if (newStep === 2) fetchReportData();
    setStep(newStep);
  };

  const PREVIEW_SCALE = 0.26;

  const ReportCoverFrame = ({ rootRef }: { rootRef?: React.RefObject<HTMLDivElement> }) => (
    <div
      ref={rootRef}
      className="relative flex flex-col overflow-hidden print-page shadow-2xl"
      style={{ width: "210mm", height: "297mm", background: "#ffffff", fontFamily: "'Open Sans', sans-serif" }}
    >
      <div className="w-full relative overflow-hidden shrink-0" style={{ height: "48%" }}>
        {coverData.bgUrl ? (
          <>
            <img src={coverData.bgUrl} alt="Cover" className="w-full h-full object-cover object-center" crossOrigin="anonymous" />
          </>
        ) : (
          <div className="w-full h-full" style={{ background: "#1e293b" }} />
        )}
      </div>
      <div className="w-full shrink-0" style={{ height: "4px", background: "#2563eb", marginTop: "0px" }} />
      <div className="flex-1 flex flex-col items-center pb-12 px-16 text-center" style={{ paddingTop: "20px" }}>
        {coverData.logoUrl && (
          <div className="mb-6 h-20 flex items-center justify-center">
            <img src={coverData.logoUrl} alt="Logo" className="max-h-16 object-contain" crossOrigin="anonymous" />
          </div>
        )}
        <h1 className="text-[44px] leading-tight font-black uppercase tracking-wide whitespace-pre-wrap" style={{ color: "#0f172a", marginTop: "20px", marginBottom: "16px" }}>{coverData.title}</h1>
        <div className="h-1 w-20 rounded-full mb-6" style={{ background: "#2563eb" }} />
        <div className="flex flex-col items-center mb-6 flex-1 justify-center">
          <span className="text-xs font-bold uppercase mb-3" style={{ color: "#64748b", letterSpacing: "0.25em" }}>Prepared For</span>
          <h2 className="text-[28px] leading-snug font-bold max-w-2xl" style={{ color: "#1e293b" }}>{coverData.companyName || "Association Name"}</h2>
        </div>
        <div className="mb-8">
          <div className="inline-flex items-center justify-center px-8 py-3 rounded" style={{ background: "#f8fafc", border: "1px solid #e2e8f0" }}>
            <p className="text-[14px] font-bold uppercase" style={{ color: "#0f172a", letterSpacing: "0.15em" }}>{coverData.date}</p>
          </div>
        </div>
        <div className="mt-auto w-full pt-6" style={{ borderTop: "1px solid #e2e8f0" }}>
          <p className="text-[10px] font-bold uppercase mb-1" style={{ color: "#64748b", letterSpacing: "0.2em" }}>Prepared By</p>
          <p className="text-[14px] font-bold" style={{ color: "#1e293b" }}>{coverData.preparedBy}</p>
        </div>
      </div>
    </div>
  );

  const ReportCover = ({ isPreview = false, rootRef }: { isPreview?: boolean; rootRef?: React.RefObject<HTMLDivElement> }) => {
    if (!isPreview) {
      return <ReportCoverFrame rootRef={rootRef} />;
    }

    return (
      <div className="w-full flex justify-center">
        <div
          className="relative"
          style={{
            width: `calc(210mm * ${PREVIEW_SCALE})`,
            height: `calc(297mm * ${PREVIEW_SCALE})`,
          }}
        >
          <div className="absolute left-0 top-0 origin-top-left" style={{ transform: `scale(${PREVIEW_SCALE})` }}>
            <ReportCoverFrame />
          </div>
        </div>
      </div>
    );
  };

  const steps2UI = [
    { num: 1, label: "Cover & Modules", icon: Layout },
    { num: 2, label: "Preview & Export", icon: Eye },
  ];

  const enabledCount = reportEntries.filter((e) => e.enabled).length;

  return (
    <div className="p-4 md:p-8 max-w-6xl mx-auto space-y-6 pb-20">
      <Card>
        <CardContent className="p-6">
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6 items-end">
            <div className="space-y-2">
              <Label>Association</Label>
              <Select value={selectedAssociationId} onValueChange={setSelectedAssociationId}>
                <SelectTrigger><SelectValue placeholder="Select Association" /></SelectTrigger>
                <SelectContent>
                  {associations.map((a) => (
                    <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Start Date</Label>
              <Input type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} />
            </div>
            <div className="space-y-2">
              <Label>End Date</Label>
              <Input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} />
            </div>
          </div>
        </CardContent>
      </Card>

      <Card className="p-6">
        <h1 className="text-2xl font-bold text-foreground mb-2">Report Builder</h1>
        <p className="text-muted-foreground mb-8">Drag to reorder sections. Page numbers auto-update. Add attachments for external documents.</p>

        <div className="flex items-center justify-between relative max-w-xs mx-auto">
          <div className="absolute left-0 top-1/2 -translate-y-1/2 w-full h-1 bg-muted rounded-full z-0" />
          <div className="absolute left-0 top-1/2 -translate-y-1/2 h-1 bg-primary rounded-full z-0 transition-all duration-500" style={{ width: `${((step - 1) / (steps2UI.length - 1)) * 100}%` }} />
          {steps2UI.map((s) => (
            <div key={s.num} className="relative z-10 flex flex-col items-center gap-2">
              <button
                onClick={() => goToStep(s.num)}
                className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-sm transition-all shadow-sm ${
                  step >= s.num ? "bg-primary text-primary-foreground ring-4 ring-primary/10" : "bg-background text-muted-foreground border-2 hover:border-primary/50"
                }`}
              >
                <s.icon className="w-5 h-5" />
              </button>
              <span className={`text-xs font-semibold ${step >= s.num ? "text-primary" : "text-muted-foreground"}`}>{s.label}</span>
            </div>
          ))}
        </div>
      </Card>

      <div className="min-h-[500px]">
        {step === 1 && (
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
            <div className="space-y-6">
              {/* Cover Page */}
              <Card>
                <CardHeader>
                  <CardTitle className="flex items-center gap-2"><Layout className="w-5 h-5 text-primary" />Cover Page</CardTitle>
                </CardHeader>
                <CardContent className="space-y-4">
                  <div className="space-y-1">
                    <Label>Report Title</Label>
                    <Textarea name="title" value={coverData.title} onChange={handleCoverChange} rows={2} className="font-semibold" />
                  </div>
                  {([["companyName", "Association Name"], ["date", "Report Date"], ["preparedBy", "Prepared By"], ["logoUrl", "Logo URL"], ["bgUrl", "Background Image URL"]] as const).map(([name, label]) => (
                    <div key={name} className="space-y-1">
                      <Label>{label}</Label>
                      <Input name={name} value={coverData[name]} onChange={handleCoverChange} />
                    </div>
                  ))}
                </CardContent>
              </Card>

              {/* Unified Draggable Report Sections */}
              <Card>
                <CardHeader className="flex flex-row items-center justify-between space-y-0">
                  <CardTitle className="flex items-center gap-2"><CheckSquare className="w-5 h-5 text-primary" />Report Sections</CardTitle>
                  <span className="text-xs text-muted-foreground">{enabledCount} enabled</span>
                </CardHeader>
                <CardContent className="space-y-4">
                  <p className="text-sm text-muted-foreground">Drag to reorder. Page numbers auto-calculate (Cover=1, TOC=2, content starts at 3).</p>

                  <DragDropContext onDragEnd={onDragEnd}>
                    <StrictModeDroppable droppableId="report-entries">
                      {(provided) => (
                        <div ref={provided.innerRef} {...provided.droppableProps} className="space-y-1">
                          {reportEntries.map((entry, index) => (
                            <Draggable key={entry.id} draggableId={entry.id} index={index}>
                              {(dragProvided, snapshot) => (
                                <div
                                  ref={dragProvided.innerRef}
                                  {...dragProvided.draggableProps}
                                  className={`flex items-center gap-2 p-2.5 rounded-lg border transition-all ${
                                    snapshot.isDragging ? "shadow-lg border-primary/50 bg-background" :
                                    entry.enabled ? "bg-primary/5 border-primary/20" : "bg-muted/30 border-transparent"
                                  }`}
                                >
                                  <div {...dragProvided.dragHandleProps} className="cursor-grab active:cursor-grabbing shrink-0">
                                    <GripVertical className="w-4 h-4 text-muted-foreground" />
                                  </div>
                                  <Checkbox checked={entry.enabled} onCheckedChange={() => toggleEntry(entry.id)} />
                                  <div className="flex-1 min-w-0">
                                    <div className="flex items-center gap-1.5">
                                      {entry.type === "attachment" && <Paperclip className="w-3 h-3 text-muted-foreground shrink-0" />}
                                      <span className="text-sm font-medium text-foreground truncate">{entry.label}</span>
                                    </div>
                                    {entry.type === "attachment" && (
                                      <div>
                                        <span className="text-[10px] text-muted-foreground">
                                          {entry.file ? `📎 ${entry.file.name}` : `${entry.pageCount} page${entry.pageCount > 1 ? "s" : ""} (no file)`}
                                        </span>
                                        {entry.summarizing && (
                                          <span className="text-[10px] text-primary flex items-center gap-1 mt-0.5">
                                            <Loader2 className="w-3 h-3 animate-spin" /> Generating AI summary…
                                          </span>
                                        )}
                                        {entry.aiSummary && !entry.summarizing && (
                                          <p className="text-[10px] text-muted-foreground mt-0.5 line-clamp-2 italic">✦ {entry.aiSummary}</p>
                                        )}
                                      </div>
                                    )}
                                  </div>
                                  <span className="text-xs font-mono text-muted-foreground w-8 text-right shrink-0">
                                    {entry.enabled ? `p.${pageNumbers.get(entry.id) || "?"}` : "—"}
                                  </span>
                                  {entry.type === "attachment" && (
                                    <Button variant="ghost" size="icon" className="h-6 w-6 shrink-0" onClick={() => removeEntry(entry.id)}>
                                      <Trash2 className="w-3 h-3 text-destructive" />
                                    </Button>
                                  )}
                                </div>
                              )}
                            </Draggable>
                          ))}
                          {provided.placeholder}
                        </div>
                      )}
                    </StrictModeDroppable>
                  </DragDropContext>

                  {/* Add Attachment */}
                  <div className="border-t pt-4">
                    <Label className="text-xs font-semibold text-muted-foreground mb-2 flex items-center gap-1.5">
                      <Paperclip className="w-3.5 h-3.5" /> Add Attachment Section
                    </Label>
                    <div className="space-y-2 mt-2">
                      <div className="space-y-1">
                        <Label className="text-xs">PDF File</Label>
                        <Input ref={fileInputRef} type="file" accept=".pdf,application/pdf" onChange={handleAttachmentFileChange} className="text-xs" />
                      </div>
                      <div className="flex gap-2 items-end">
                        <div className="flex-1 space-y-1">
                          <Label className="text-xs">Title</Label>
                          <Input placeholder="e.g. Financial Summary" value={newAttLabel} onChange={(e) => setNewAttLabel(e.target.value)} onKeyDown={(e) => e.key === "Enter" && addAttachment()} />
                        </div>
                        <div className="w-20 space-y-1">
                          <Label className="text-xs">Pages</Label>
                          <Input type="number" min="1" value={newAttPages} onChange={(e) => setNewAttPages(e.target.value)} onKeyDown={(e) => e.key === "Enter" && addAttachment()} />
                        </div>
                        <Button size="icon" variant="outline" onClick={addAttachment} className="shrink-0"><Plus className="w-4 h-4" /></Button>
                      </div>
                      {newAttFile && <p className="text-[10px] text-muted-foreground">📎 {newAttFile.name}</p>}
                    </div>
                  </div>
                </CardContent>
              </Card>
            </div>

            <div className="hidden lg:flex items-start justify-center bg-muted/30 rounded-xl border shadow-inner overflow-hidden h-[800px] p-8">
              <div className="w-full flex justify-center pt-2">
                <ReportCover isPreview />
              </div>
            </div>
          </div>
        )}

        {step === 2 && (
          <div className="flex flex-col items-center space-y-4">
            <div className="w-full flex justify-between items-center">
              <div className="text-sm text-muted-foreground">
                {dataLoading ? (
                  <span className="flex items-center gap-2"><Loader2 className="w-4 h-4 animate-spin" /> Loading data…</span>
                ) : (
                  <span>{getOrderedEnabledEntries().length} sections</span>
                )}
              </div>
              <div className="flex gap-3">
                <Button variant="outline" onClick={handlePrint}><Printer className="w-4 h-4 mr-2" /> Print</Button>
                <Button onClick={generatePDF} disabled={isExporting || dataLoading}>
                  {isExporting ? <><Loader2 className="w-4 h-4 mr-2 animate-spin" />Generating…</> : <><Download className="w-4 h-4 mr-2" /> Export PDF</>}
                </Button>
              </div>
            </div>

            <div className="bg-muted/30 p-6 w-full overflow-x-auto rounded-xl shadow-inner">
              <div ref={previewRef} className="max-w-4xl mx-auto space-y-8">
                {dataLoading ? (
                  <div className="flex items-center justify-center h-64">
                    <Loader2 className="w-8 h-8 animate-spin text-primary" />
                  </div>
                ) : getOrderedEnabledEntries().length === 0 ? (
                  <div className="flex flex-col items-center justify-center h-64 text-center">
                    <FileText className="w-12 h-12 text-muted-foreground/40 mb-3" />
                    <h3 className="text-lg font-semibold text-foreground">No Data Found</h3>
                    <p className="text-sm text-muted-foreground">No records found for the selected modules and date range.</p>
                  </div>
                ) : (
                  (() => {
                    let sectionNum = 0;
                    return getOrderedEnabledEntries().map((entry) => {
                      sectionNum++;
                      if (entry.type === "attachment") {
                        return (
                          <Card key={entry.id}>
                            <CardHeader className="pb-3">
                              <CardTitle className="flex items-center gap-3 text-lg">
                                <span className="w-8 h-8 bg-muted text-muted-foreground rounded-lg flex items-center justify-center text-sm font-bold">{sectionNum}</span>
                                <Paperclip className="w-4 h-4 text-muted-foreground" />
                                {entry.label}
                                <span className="ml-auto text-sm font-normal text-muted-foreground">{entry.pageCount} page{entry.pageCount > 1 ? "s" : ""} (attachment)</span>
                              </CardTitle>
                            </CardHeader>
                            <CardContent>
                              {entry.aiSummary && (
                                <div className="mb-3 p-3 bg-primary/5 rounded-lg border border-primary/10">
                                  <p className="text-xs font-semibold text-foreground mb-1">✦ Executive Summary</p>
                                  <p className="text-sm text-muted-foreground italic">{entry.aiSummary}</p>
                                </div>
                              )}
                              {entry.summarizing && (
                                <div className="mb-3 flex items-center gap-2 text-sm text-primary">
                                  <Loader2 className="w-4 h-4 animate-spin" /> Generating AI summary…
                                </div>
                              )}
                              <p className="text-sm text-muted-foreground italic">This section represents an external attachment. Placeholder pages will be included in the exported PDF at page {pageNumbers.get(entry.id) || "?"}.</p>
                            </CardContent>
                          </Card>
                        );
                      }
                      const mod = DATA_MODULES.find((m) => m.key === entry.moduleKey)!;
                      return (
                        <Card key={entry.id}>
                          <CardHeader className="pb-3">
                            <CardTitle className="flex items-center gap-3 text-lg">
                              <span className="w-8 h-8 bg-primary text-primary-foreground rounded-lg flex items-center justify-center text-sm font-bold">{sectionNum}</span>
                              {mod.label}
                              <span className="ml-auto text-sm font-normal text-muted-foreground">{reportData[mod.key].length} records</span>
                            </CardTitle>
                          </CardHeader>
                          <CardContent className="p-0">
                            <div className="overflow-x-auto">
                              <table className="w-full text-sm">
                                <thead>
                                  <tr className="bg-muted/50">
                                    {mod.columns.map((col) => (
                                      <th key={col} className="text-left px-4 py-2 font-semibold text-muted-foreground text-xs uppercase tracking-wide border-b">{col}</th>
                                    ))}
                                  </tr>
                                </thead>
                                <tbody>
                                  {reportData[mod.key].map((row: any, ri: number) => (
                                    <tr key={ri} className={ri % 2 === 0 ? "" : "bg-muted/20"}>
                                      {mod.fields.map((f) => (
                                        <td key={f} className="px-4 py-2 text-foreground/80 border-b border-muted/50 text-xs">{getCellValue(row, f)}</td>
                                      ))}
                                    </tr>
                                  ))}
                                </tbody>
                              </table>
                            </div>
                          </CardContent>
                        </Card>
                      );
                    });
                  })()
                )}
              </div>
            </div>
          </div>
        )}
      </div>

      <div className="flex items-center justify-between pt-6 border-t">
        <Button variant="outline" onClick={() => goToStep(step - 1)} disabled={step === 1} className="h-12 px-6">
          <ArrowLeft className="w-4 h-4 mr-2" /> Back
        </Button>
        {step === 1 ? (
          <Button onClick={() => goToStep(2)} disabled={!selectedAssociationId} className="h-12 px-8">
            Preview & Export <ArrowRight className="w-4 h-4 ml-2" />
          </Button>
        ) : null}
      </div>

    </div>
  );
}
