import { jsPDF } from "jspdf";
import autoTable from "jspdf-autotable";
import { format } from "date-fns";

const drawCheckboxGlyph = (doc, checked, x, baselineY) => {
  const fontSize = doc.getFontSize();
  const size = Math.max(7, fontSize * 0.9);
  const top = baselineY - size + 1;
  doc.setDrawColor(0, 0, 0);
  doc.setLineWidth(0.7);
  doc.rect(x, top, size, size);
  if (checked) {
    const pad = size * 0.22;
    doc.setLineWidth(1.1);
    doc.line(x + pad, top + pad, x + size - pad, top + size - pad);
    doc.line(x + size - pad, top + pad, x + pad, top + size - pad);
  }
  doc.setLineWidth(0.2);
};

// Draw a checkbox followed by a label. Returns total width consumed.
const drawCheckboxLabel = (doc, checked, label, x, baselineY) => {
  const fontSize = doc.getFontSize();
  const boxSize = Math.max(7, fontSize * 0.9);
  const gap = fontSize * 0.35;
  drawCheckboxGlyph(doc, checked, x, baselineY);
  doc.text(label, x + boxSize + gap, baselineY);
  return boxSize + gap + doc.getTextWidth(label);
};

export async function generateEstoppelPdf(data, logoUrl, returnBlob = false) {
  const doc = new jsPDF({ unit: "pt", format: "letter" });

  const pw = doc.internal.pageSize.getWidth(); // 612
  const ph = doc.internal.pageSize.getHeight(); // 792
  const m = 40;
  const cw = pw - m * 2; // content width
  const fs = data.fontSize || 9;
  const fontFamily = (data.font || "Helvetica").toLowerCase() === "times" ? "times" : data.font === "Courier" ? "courier" : "helvetica";

  const setNormal = (size) => { doc.setFont(fontFamily, "normal"); doc.setFontSize(size || fs); doc.setTextColor(0, 0, 0); };
  const setBold = (size) => { doc.setFont(fontFamily, "bold"); doc.setFontSize(size || fs); doc.setTextColor(0, 0, 0); };

  let y = m;

  // --- LOGO ---
  try {
    const img = new Image();
    img.crossOrigin = "anonymous";
    await new Promise((res, rej) => { img.onload = res; img.onerror = rej; img.src = logoUrl; });
    const aspect = img.width / img.height;
    const logoH = 50;
    const logoW = logoH * aspect;
    doc.addImage(img, "PNG", m, y, logoW, logoH);
  } catch (e) {
    console.warn("Logo load failed", e);
  }

  // --- TITLE ---
  y += 10;
  setBold(16);
  doc.text("CERTIFICATE OF ESTOPPEL", pw / 2, y, { align: "center" });
  y += 25;

  setNormal(8);
  doc.setTextColor(80, 80, 80);
  doc.text("PREPARED BY:", pw / 2, y, { align: "center" });
  y += 12;
  setBold(9);
  doc.setTextColor(0, 0, 0);
  doc.text("AVRIA COMMUNITY MANAGEMENT, LLC", pw / 2, y, { align: "center" });
  y += 12;
  setNormal(8);
  doc.text("5445 MURRELL ROAD, #102-19, VIERA, FLORIDA 32955", pw / 2, y, { align: "center" });
  y += 12;
  doc.text("TEL/FAX: (321) 405-2449 <CAM@AVRIACAM.COM>", pw / 2, y, { align: "center" });
  y += 20;

  // Horizontal line
  doc.setDrawColor(0); doc.setLineWidth(0.5);
  doc.line(m, y, pw - m, y);
  y += 15;

  // --- DATE ---
  const fmtDate = data.date ? format(new Date(data.date + "T00:00:00"), "MM/dd/yyyy") : "";
  setNormal();
  doc.text(fmtDate, m, y);
  y += 18;

  // --- TO / RE / LEGAL / PARCEL ---
  const drawLabelValue = (label, value) => {
    setBold();
    doc.text(label, m, y);
    setNormal();
    const lines = doc.splitTextToSize(value || "", cw - 100);
    doc.text(lines, m + 100, y);
    y += Math.max(lines.length, 1) * (fs + 3) + 5;
  };

  drawLabelValue("TO:", data.recipientName || "");
  if (data.recipientAddress) {
    setNormal();
    const addrLines = data.recipientAddress.split("\n");
    addrLines.forEach(l => { doc.text(l, m + 100, y); y += fs + 3; });
    y += 5;
  }
  drawLabelValue("RE:", data.reReference || "");
  drawLabelValue("LEGAL DESCRIPTION:", data.legalDescription || "");
  drawLabelValue("PARCEL:", data.parcelId || "");
  drawLabelValue("BUYER / BANK:", data.buyerBank || "");
  drawLabelValue("SELLER:", data.seller || "");

  // Attachments
  setBold();
  doc.text("ATTACHED:", m, y);
  setNormal();
  {
    let cx = m + 100;
    const gap = 14;
    cx += drawCheckboxLabel(doc, !!data.attachments?.ledger, "LEDGER", cx, y) + gap;
    cx += drawCheckboxLabel(doc, !!data.attachments?.w9, "W-9", cx, y) + gap;
    drawCheckboxLabel(doc, !!data.attachments?.certApproval, "CERT. OF APPROVAL", cx, y);
  }
  y += 20;

  // --- INSTRUCTIONS ---
  doc.setDrawColor(0); doc.setLineWidth(0.5);
  doc.line(m, y, pw - m, y);
  y += 15;
  setBold(10);
  doc.text("INSTRUCTIONS", m, y);
  y += 14;
  setNormal(8);
  const instrText = "Amounts Due at Closing. Please remit due amounts via separate checks as indicated. Note that the figures provided are based on information available at the time of preparation and are subject to change without notice. Avria Community Management does not accept responsibility for any inaccuracies or omissions.";
  const instrLines = doc.splitTextToSize(instrText, cw);
  doc.text(instrLines, m, y);
  y += instrLines.length * 10 + 10;

  // Check if we need a new page
  const ensureSpace = (needed) => {
    if (y + needed > ph - 40) { doc.addPage(); y = m; }
  };

  // --- FINANCIAL TABLE ---
  ensureSpace(120);
  autoTable(doc, {
    startY: y,
    head: [["CHECK #1 PAYABLE TO:", "CHECK #2 PAYABLE TO:"]],
    body: [[data.payableTo1 || "See Below", "AVRIA COMMUNITY MANAGEMENT, LLC\n5445 MURRELL ROAD, #102-197\nVIERA, FLORIDA 32955"]],
    theme: "grid",
    styles: { fontSize: 8, cellPadding: 6, font: fontFamily },
    headStyles: { fillColor: [240, 240, 240], textColor: [0, 0, 0], fontStyle: "bold" },
    margin: { left: m, right: m },
    tableWidth: cw,
  });
  y = doc.lastAutoTable.finalY + 10;

  const fmt = (v) => `$ ${(v || 0).toFixed(2)}`;

  ensureSpace(80);
  const leftRows = [
    ["BALANCE AT CLOSE (2):", fmt(data.balanceAtClose)],
    ["ADVANCED ASSESSMENTS (3):", fmt(data.advAssessments)],
    ...(data.masterPayments || []).map((p) => [
      (p.desc || "MASTER PAYMENT") + ":",
      fmt(parseFloat(p.amount) || 0),
    ]),
    ...(data.otherAmounts || []).map((p) => [
      (p.desc || "OTHER AMOUNT") + ":",
      fmt(parseFloat(p.amount) || 0),
    ]),
  ];
  const rightRows = [
    ["ACCOUNT START-UP FEE:", fmt(data.accountStartupFee)],
    ["DELINQUENCY FEE:", fmt(data.delinquencyFee)],
  ];
  const rowCount = Math.max(leftRows.length, rightRows.length);
  const body = [];
  for (let i = 0; i < rowCount; i++) {
    const l = leftRows[i] || ["", ""];
    const r = rightRows[i] || ["", ""];
    body.push([l[0], l[1], r[0], r[1]]);
  }
  body.push([
    { content: "TOTAL DUE AT CLOSE:", styles: { fontStyle: "bold" } },
    { content: fmt(data.total1), styles: { fontStyle: "bold" } },
    { content: "TOTAL DUE AT CLOSE:", styles: { fontStyle: "bold" } },
    { content: fmt(data.total2), styles: { fontStyle: "bold" } },
  ]);
  autoTable(doc, {
    startY: y,
    body,
    theme: "grid",
    styles: { fontSize: 8, cellPadding: 5, font: fontFamily },
    margin: { left: m, right: m },
    tableWidth: cw,
    columnStyles: { 0: { cellWidth: cw * 0.3 }, 1: { cellWidth: cw * 0.2, halign: "right" }, 2: { cellWidth: cw * 0.3 }, 3: { cellWidth: cw * 0.2, halign: "right" } },
  });
  y = doc.lastAutoTable.finalY + 15;

  // --- SUMMARY BOX ---
  ensureSpace(100);
  const boxY = y;
  setBold(9);
  doc.text("Summary", m + 8, y + 14);
  y += 22;
  setNormal(8);
  const notes = [
    "1. Amounts Due at Closing. Amounts due must be remitted on separate checks as shown.",
    `2. Balance Prior to Close. As of ${fmtDate}, the account has been invoiced for all regular assessments due, including the current account balance of ${fmt(data.balanceAtClose)}. The Balance Prior to Close is an estimate.`,
    "3. Advance Assessments. Advance Assessments is an estimate of the amounts to be due for the period from closing.",
    "4. Additional Fees. The additional fees indicated above, if any, are documented on the following pages. Please review.",
  ];
  notes.forEach(n => {
    const ls = doc.splitTextToSize(n, cw - 16);
    doc.text(ls, m + 8, y);
    y += ls.length * 10 + 4;
  });
  y += 4;
  // Draw box around summary
  doc.setDrawColor(0); doc.setLineWidth(0.5);
  doc.rect(m, boxY, cw, y - boxY);
  y += 15;

  // --- QUESTIONNAIRE PAGE ---
  const drawYNQ = (num, question, value, extra) => {
    ensureSpace(22);
    setBold();
    const qText = `${num}. ${question}`;
    const qLines = doc.splitTextToSize(qText, cw * 0.55);
    doc.text(qLines, m, y);
    setNormal();

    // Compute widths so we can right-align the group
    const boxSize = Math.max(7, doc.getFontSize() * 0.9);
    const gap = doc.getFontSize() * 0.35;
    const groupGap = 14;
    const itemW = (label) => boxSize + gap + doc.getTextWidth(label);
    let totalW = itemW("YES") + groupGap + itemW("NO");
    if (extra === "na") totalW += groupGap + itemW("N/A");

    let cx = pw - m - totalW;
    cx += drawCheckboxLabel(doc, value === "yes", "YES", cx, y) + groupGap;
    cx += drawCheckboxLabel(doc, value === "no", "NO", cx, y);
    if (extra === "na") {
      cx += groupGap;
      drawCheckboxLabel(doc, value === "na", "N/A", cx, y);
    }
    y += Math.max(qLines.length, 1) * (fs + 4) + 6;
  };

  const drawTextQ = (num, question, value) => {
    ensureSpace(30);
    setBold();
    doc.text(`${num}. ${question}`, m, y);
    y += fs + 5;
    setNormal();
    const valLines = doc.splitTextToSize(value || "", cw - 20);
    doc.text(valLines, m + 20, y);
    y += valLines.length * (fs + 3) + 8;
  };

  const q = data.questionnaire;

  drawYNQ("1", "Please advise if the property is in collections?", q.q1);

  drawTextQ("2", "Assessment Rate:", `$ ${q.q2}`);
  drawTextQ("3", "Assessment Frequency:", q.q3);
  drawYNQ("4", "Is there a capital contribution fee?", q.q4);
  drawTextQ("5", "What utilities are included in maintenance?", q.q5);
  drawYNQ("6", "Are there any special assessments pending or certified?", q.q6);
  drawYNQ("7", "Are there multiple associations?", q.q7);
  drawYNQ("7b", "Is another estoppel required?", q.q7b);
  drawYNQ("8", "Is the association currently part of any litigation?", q.q8);

  // Q9 - Address
  ensureSpace(40);
  setBold();
  doc.text("9.       Address to send assessments:", m, y);
  y += fs + 5;
  setNormal();
  const addrLines = (q.q9 || "").split("\n");
  addrLines.forEach(l => {
    doc.text(l.trim(), m + 40, y);
    y += fs + 3;
  });
  y += 8;

  // Q10 breakdown - delinquent amounts table
  ensureSpace(120);
  setBold();
  doc.text("10.       Delinquent Amounts:", m, y);
  y += 15;

  autoTable(doc, {
    startY: y,
    body: [
      [{ content: "a. Total unpaid assessments:", styles: {} }, { content: fmt(q.q10.unpaid), styles: { halign: "right" } }],
      [{ content: "b. Fines:", styles: {} }, { content: fmt(0), styles: { halign: "right" } }],
      [{ content: "c. Interest:", styles: {} }, { content: fmt(q.q10.interest), styles: { halign: "right" } }],
      [{ content: "d. Late Fees:", styles: {} }, { content: fmt(q.q10.late), styles: { halign: "right" } }],
      [{ content: "e. Attorneys' Fees:", styles: {} }, { content: fmt(q.q10.legal), styles: { halign: "right" } }],
      [{ content: "f. TOTAL DELINQUENT AMOUNT:", styles: { fontStyle: "bold" } }, { content: fmt(q.q10.unpaid + q.q10.interest + q.q10.late + q.q10.admin + q.q10.legal), styles: { fontStyle: "bold", halign: "right" } }],
    ],
    theme: "plain",
    styles: { fontSize: 8, cellPadding: 4, font: fontFamily },
    margin: { left: m + 40, right: m },
    tableWidth: cw - 40,
    columnStyles: {
      0: { cellWidth: (cw - 40) * 0.7 },
      1: { cellWidth: (cw - 40) * 0.3, fillColor: [240, 240, 240] },
    },
    alternateRowStyles: {},
    didDrawCell: (data) => {
      if (data.column.index === 1) {
        doc.setDrawColor(200);
        doc.setLineWidth(0.3);
        doc.line(data.cell.x, data.cell.y + data.cell.height, data.cell.x + data.cell.width, data.cell.y + data.cell.height);
      }
    },
  });
  y = doc.lastAutoTable.finalY + 12;

  // Q11
  drawYNQ("11", "Are late fees included in this payoff?", q.q13);

  // Q12 - Other amounts due
  ensureSpace(30);
  setBold();
  doc.text("12. Other amounts due:", m, y);
  y += fs + 5;
  setNormal();
  if (q.q11.length === 0) {
    doc.text("None", m + 20, y);
  } else {
    q.q11.forEach((c) => {
      doc.text(`${c.desc || "Item"}:  $ ${(parseFloat(c.amount) || 0).toFixed(2)}`, m + 20, y);
      y += fs + 5;
    });
  }
  y += 12;

  // Q13 - Total Payoff
  ensureSpace(25);
  setBold();
  doc.text("13. Total Payoff Amount Due at Closing:", m, y);
  setNormal();
  const payoffStr = fmt(q.q12Payoff);
  // Draw with gray background
  const payoffW = doc.getTextWidth(payoffStr) + 16;
  doc.setFillColor(240, 240, 240);
  doc.rect(pw - m - payoffW, y - 9, payoffW, 14, "F");
  doc.text(payoffStr, pw - m - 8, y, { align: "right" });
  y += 22;

  // Remaining questions
  ensureSpace(20);
  drawTextQ("14", "Date next assessment is due:", q.q14);
  drawTextQ("15", "What is the estoppel fee?", `$ ${q.q15.toFixed(2)}`);
  drawYNQ("15a", "Has the estoppel fee been paid?", q.q15a);
  drawYNQ("16", "Is there a recreational lease/contract?", q.q16);
  drawYNQ("17", "Are there any violations or code enforcement issues?", q.q17);
  drawYNQ("18", "Is a Certificate of Approval required?", q.q18);
  drawYNQ("19", "Is there a background check fee?", q.q19);
  drawYNQ("20", "Has application been made?", q.q20, "na");
  drawYNQ("21", "Are there any land leases?", q.q21);
  drawYNQ("22", "Are there parking restrictions?", q.q22);
  drawYNQ("23", "Right of first refusal?", q.q23);
  drawYNQ("24", "Foreclosure clause?", q.q24);
  drawYNQ("25", "Is board approval required for transfer?", q.q25);
  drawYNQ("26", "Is the property subject to any liens?", q.q26);
  drawTextQ("27", "Master Insurance Policy details:", q.q27);
  drawTextQ("28", "Flood Insurance Policy details:", q.q28);

  if (data.masterAssocInfo) {
    ensureSpace(40);
    setBold();
    doc.text("Master Association Information:", m, y);
    y += 14;
    setNormal();
    const ml = doc.splitTextToSize(data.masterAssocInfo, cw);
    doc.text(ml, m, y);
    y += ml.length * 10 + 10;
  }

  if (data.additionalInfo) {
    ensureSpace(40);
    setBold();
    doc.text("Additional Information:", m, y);
    y += 14;
    setNormal();
    const al = doc.splitTextToSize(data.additionalInfo, cw);
    doc.text(al, m, y);
    y += al.length * 10 + 10;
  }

  if (returnBlob) {
    return doc.output("blob");
  }

  doc.save("Estoppel_Certificate.pdf");
  return doc;
}
