// Marked-up insurance estimate PDF generator.
//
// The vendor enters a markup % (capped 0–40%, step 5) and we open
// a print-friendly window with:
//   - Precision Cabinets branded header (logo, name, address, contact)
//     so the document reads as a real estimate FROM Precision TO the
//     vendor — what the adjuster expects to see from a cabinet shop.
//   - Aggregate totals only: total Materials and total Labor for the
//     entire order, plus derived $/linear-foot. NO per-cabinet line
//     items — the adjuster gets a clean unit-cost narrative.
//   - Photo gallery of cabinets (when photos are present), labeled by
//     cabinet name.
//   - NO Precision contract pricing. Only the marked-up totals.
//
// We deliberately avoid shipping a PDF library — window.print() to
// "Save as PDF" works on every Windows / Mac / iOS device the vendors
// own and adds zero bytes to the bundle.

(function () {
  // Precision Cabinets shop info — pulled from the admin-editable
  // companyInfo/current Firestore doc. ensureCompanyInfo() caches
  // the latest doc on window.PC_COMPANY_INFO; if it hasn't loaded
  // yet (offline / first call), we fall back to these defaults.
  const PRECISION_DEFAULTS = {
    name: 'Precision Cabinets LLC',
    addressLine1: '3319 E Fandango Dr',
    addressLine2: 'Gilbert, AZ 85298',
    phone: 'TBD',
    email: 'estimates@precisioncabinetsllc.com',
    website: 'precisioncabinetsllc.com',
    logoUrl: '',
  };
  function getPrecisionInfo() {
    return Object.assign({}, PRECISION_DEFAULTS, window.PC_COMPANY_INFO || {});
  }

  function fmtUsd(n) {
    if (!isFinite(n) || n == null) return '$0.00';
    return n.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
  }

  function escapeHtml(s) {
    if (s == null) return '';
    return String(s)
      .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
  }

  // Sum cabinet widths in inches (cabinet-side widths) and convert
  // to linear feet. We use the cabinet width as the install run
  // contribution — typical shop convention.
  function totalLinearFeet(cabinets) {
    if (!Array.isArray(cabinets)) return 0;
    let inches = 0;
    for (const c of cabinets) {
      const wIn = parseFloat(String(c.w || 0)) || 0;
      const unit = c.wu || 'in';
      const inchesEach = unit === 'ft' ? wIn * 12 : wIn;
      inches += inchesEach;
    }
    return inches / 12;
  }

  function buildHtml({ vendor, data, pricing, markupPercent }) {
    const PRECISION = getPrecisionInfo();
    const computeEstimate = window.computeEstimate;
    const precisionTotal = (computeEstimate ? computeEstimate(data, pricing).total : 0) || 0;
    const markup = Math.max(0, Math.min(40, markupPercent || 0));
    const markedUpTotal = precisionTotal * (1 + markup / 100);

    // Materials/Labor split — pull from shopConstants when present,
    // fall back to 60/40 if it hasn't loaded yet.
    const split = (window.PC_SHOP_CONSTANTS && window.PC_SHOP_CONSTANTS.materialsLaborSplit) || 0.6;
    const materialsTotal = markedUpTotal * split;
    const laborTotal = markedUpTotal * (1 - split);

    const linFt = totalLinearFeet(data.cabinets || []);
    const matsPerLf = linFt > 0 ? materialsTotal / linFt : 0;
    const laborPerLf = linFt > 0 ? laborTotal / linFt : 0;

    const cabinetsWithPhotos = (data.cabinets || []).filter(c => c.photo);
    const photoSection = cabinetsWithPhotos.length === 0 ? '' : `
      <h2>Scope of Work — Cabinets to be Repaired or Replaced</h2>
      <div class="photo-grid">
        ${cabinetsWithPhotos.map((c, i) => `
          <div class="photo-cell">
            <img src="${escapeHtml(c.photo)}" alt="${escapeHtml(c.name || 'Cabinet ' + (i + 1))}" />
            <div class="photo-cap">${escapeHtml(c.name || ('Cabinet ' + (i + 1)))} · ${escapeHtml(c.w || '?')}"×${escapeHtml(c.h || '?')}"×${escapeHtml(c.d || '?')}"</div>
          </div>
        `).join('')}
      </div>
    `;

    const datePrepared = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });

    return `<!doctype html>
<html><head><meta charset="utf-8"/>
<title>Estimate — ${escapeHtml(data.clientName || 'Insurance')}</title>
<style>
  * { box-sizing: border-box; }
  body { font-family: 'Helvetica Neue', Arial, sans-serif; color: #111; margin: 0; padding: 32px; background: #fff; }
  .header { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 3px solid #0a2240; padding-bottom: 16px; margin-bottom: 24px; }
  .brand { display: flex; gap: 14px; align-items: center; }
  .brand-mark { width: 56px; height: 56px; background: #0a2240; color: #f0c14b; display: flex; align-items: center; justify-content: center; font-family: Georgia, serif; font-weight: bold; font-size: 28px; border-radius: 6px; }
  .brand-text { font-family: Georgia, serif; }
  .brand-text .name { font-size: 22px; font-weight: bold; color: #0a2240; }
  .brand-text .tag { font-size: 11px; color: #b08720; letter-spacing: 1px; text-transform: uppercase; }
  .shop-info { font-size: 11px; color: #555; line-height: 1.5; text-align: right; }
  h1 { font-size: 18px; margin: 16px 0 4px; color: #0a2240; }
  h2 { font-size: 14px; margin: 24px 0 8px; color: #b08720; border-bottom: 1px solid #ddd; padding-bottom: 4px; }
  .billto { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 16px; font-size: 12px; }
  .billto .label { font-size: 10px; text-transform: uppercase; color: #888; letter-spacing: 0.5px; }
  table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; border: 1px solid #999; }
  th { text-align: left; padding: 8px 10px; background: #0a2240; color: #fff; font-weight: 600; text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px; }
  td { padding: 8px 10px; border-bottom: 1px solid #eee; }
  td.r { text-align: right; font-family: 'SF Mono', 'Consolas', monospace; }
  tfoot td { font-weight: bold; background: #fdf8e9; border-top: 2px solid #0a2240; }
  tfoot td.r { font-size: 14px; color: #0a2240; }
  .totals-row td { padding: 12px 10px; }
  .toolbar { display: flex; gap: 8px; margin-bottom: 24px; }
  .btn { background: #0a2240; color: white; border: 0; padding: 10px 18px; border-radius: 6px; font-size: 13px; cursor: pointer; font-weight: 600; }
  .btn.secondary { background: #f3f4f6; color: #0a2240; }
  .meta-line { font-size: 11px; color: #555; margin: 4px 0; }
  .photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 8px; }
  .photo-cell img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 6px; border: 1px solid #ddd; }
  .photo-cap { font-size: 10px; color: #555; margin-top: 4px; text-align: center; }
  .footer { margin-top: 32px; font-size: 10px; color: #888; border-top: 1px solid #eee; padding-top: 8px; line-height: 1.5; }
  .footer strong { color: #555; }
  @media print { .no-print { display: none; } body { padding: 16px; } }
</style>
</head><body>

<!-- In the embedded preview the parent app provides its own toolbar.
     If the user opens this HTML in a new tab via "Open in new tab",
     the toolbar shows so they can print directly. -->
<div class="toolbar no-print" id="pcToolbar">
  <button class="btn" onclick="window.print()">Print / Save as PDF</button>
  <button class="btn secondary" onclick="window.close()">Close</button>
</div>
<script>
  // Hide the inline toolbar when this document is loaded inside an
  // iframe (the preview modal already provides Print/Close).
  if (window.parent !== window) {
    var t = document.getElementById('pcToolbar');
    if (t) t.style.display = 'none';
  }
</script>

<div class="header">
  <div class="brand">
    ${PRECISION.logoUrl
      ? `<img src="${escapeHtml(PRECISION.logoUrl)}" alt="${escapeHtml(PRECISION.name)} logo" style="width:64px;height:64px;object-fit:contain;border-radius:6px;background:#0a2240;padding:6px;" />`
      : `<div class="brand-mark">PC</div>`}
    <div class="brand-text">
      <div class="name">${escapeHtml(PRECISION.name)}</div>
      <div class="tag">Cabinetry · Repair · Refacing</div>
    </div>
  </div>
  <div class="shop-info">
    ${escapeHtml(PRECISION.addressLine1)}<br/>
    ${escapeHtml(PRECISION.addressLine2)}<br/>
    ${escapeHtml(PRECISION.phone)}<br/>
    ${escapeHtml(PRECISION.email)}<br/>
    ${escapeHtml(PRECISION.website)}
  </div>
</div>

<h1>Estimate</h1>
<div class="meta-line">Prepared ${escapeHtml(datePrepared)}</div>

<div class="billto" style="margin-top: 16px;">
  <div>
    <div class="label">Prepared for</div>
    <div><strong>${escapeHtml(vendor.name || data.vendorName || '')}</strong></div>
    ${data.vendorContact ? `<div>${escapeHtml(data.vendorContact)}</div>` : ''}
    ${data.vendorPhone ? `<div>${escapeHtml(data.vendorPhone)}</div>` : ''}
    ${data.vendorEmail ? `<div>${escapeHtml(data.vendorEmail)}</div>` : ''}
  </div>
  <div>
    <div class="label">Project</div>
    <div><strong>${escapeHtml(data.clientName || '')}</strong></div>
    ${data.address ? `<div>${escapeHtml(data.address)}</div>` : ''}
    ${data.completionRequested ? `<div>Target: ${escapeHtml(data.completionRequested)}</div>` : ''}
  </div>
</div>

${photoSection}

<h2>Estimate Summary</h2>
<div class="meta-line">
  ${(data.cabinets || []).length} cabinet${(data.cabinets || []).length === 1 ? '' : 's'}
  · ${linFt.toFixed(1)} linear ft of cabinetry
</div>
<table>
  <thead>
    <tr>
      <th style="width: 50%;">Description</th>
      <th class="r" style="width: 25%;">$ / linear ft</th>
      <th class="r" style="width: 25%;">Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Materials — cabinet boxes, face frame, drawer boxes, hardware, finish</td>
      <td class="r">${linFt > 0 ? fmtUsd(matsPerLf) : '—'}</td>
      <td class="r">${fmtUsd(materialsTotal)}</td>
    </tr>
    <tr>
      <td>Labor — fabrication, finishing, delivery, installation</td>
      <td class="r">${linFt > 0 ? fmtUsd(laborPerLf) : '—'}</td>
      <td class="r">${fmtUsd(laborTotal)}</td>
    </tr>
  </tbody>
  <tfoot>
    <tr class="totals-row">
      <td>Estimate total</td>
      <td class="r"></td>
      <td class="r">${fmtUsd(markedUpTotal)}</td>
    </tr>
  </tfoot>
</table>

<div class="footer">
  <strong>Notes.</strong> This estimate covers the scope of cabinetry shown above based on the vendor's intake.
  Final pricing may vary if additional damage, modifications, or change orders are identified during fabrication
  or installation. Estimate valid for 30 days from date prepared.
  <br/><br/>
  <strong>${escapeHtml(PRECISION.name)}</strong> · ${escapeHtml(PRECISION.phone)} · ${escapeHtml(PRECISION.email)}
</div>

</body></html>`;
  }

  // Cache shop constants for the materials/labor split. Lazy-loaded
  // on first PDF open so we don't hit Firestore on every page load.
  function ensureShopConstants() {
    if (window.PC_SHOP_CONSTANTS) return Promise.resolve(window.PC_SHOP_CONSTANTS);
    if (!window.db) return Promise.resolve(null);
    return window.db.collection('shopConstants').doc('current').get()
      .then(snap => { if (snap.exists) window.PC_SHOP_CONSTANTS = snap.data(); return window.PC_SHOP_CONSTANTS; })
      .catch(() => null);
  }

  // Render the HTML synchronously. Async wrappers tear up the
  // user-gesture context that browsers require to open a new tab,
  // which is why the original window.open() approach got blocked.
  function buildInsuranceEstimateHtml({ vendor, data, pricing, markupPercent }) {
    return buildHtml({ vendor, data, pricing, markupPercent });
  }

  // Best-effort window.open — caller must already be inside a click
  // handler (no awaits before this call) for the popup to be allowed.
  function openInsuranceEstimatePdf({ vendor, data, pricing, markupPercent }) {
    const html = buildHtml({ vendor, data, pricing, markupPercent });
    const win = window.open('', '_blank');
    if (!win) {
      // Fall back to a Blob URL. Some browsers block window.open even
      // inside a click; redirecting the same tab works because it's
      // navigation, not a popup. We open in the same tab as a last
      // resort — the user can use the back button to return.
      try {
        const blob = new Blob([html], { type: 'text/html' });
        const url = URL.createObjectURL(blob);
        window.location.assign(url);
        return true;
      } catch {
        alert('Could not open the PDF preview. Try again from your browser without "Add to Home Screen" mode.');
        return false;
      }
    }
    win.document.open();
    win.document.write(html);
    win.document.close();
    return true;
  }

  function ensureShopConstantsAsync() { return ensureShopConstants(); }

  Object.assign(window, {
    openInsuranceEstimatePdf,
    buildInsuranceEstimateHtml,
    ensureShopConstantsAsync,
  });
})();
