// ============================================
// ScopeSummaryPDF.ts
// Generates a Scope Summary Report HTML page in a new browser tab.
// Layout matches the existing HBS template exactly.
// ============================================

interface AuditStage {
  stageName: string;        // "Stage 1" | "Stage 2" | "Surveillance 1" etc.
  auditDate: string;        // "DD-MMM-YYYY"
  anzicCode?: string;
  auditor?: {
    firstName?: string;
    lastName?: string;
  } | null;
  technicalExpert?: string;
}

interface ScopeSummaryData {
  // Job header info
  jobId?: number | string;
  jobCode?: string | null;
  clientGroup?: string;

  // Company snapshot
  company: {
    name: string;
    address?: string;
    contact_person?: string;
    designation?: string;
    email?: string;
    mobile?: string;
    telephone?: string;
    fax?: string;
    certification_body?: string;
    accreditation?: string;
    scope_of_work?: string;
    validity?: string;
  };

  // Standards
  standards?: { name: string }[];

  // Audit stages
  stages: AuditStage[];

  // Optional remarks
  remarks?: string;
}

// ✅ FIXED — logo path now points to /globe.png
const LOGO_URL = '/globe.png';
const TQS_LOGO_URL = 'https://tqs.ae/images/logo.png';


function formatScopeText(scope?: string): string {
  if (!scope || !scope.trim()) return 'N/A';

  const cleaned = scope.trim();

  // Try splitting by common separators
  const parts = cleaned
    .split(/[;|]+/)
    .map((s) => s.trim())
    .filter(Boolean);

  if (parts.length > 1) {
    return `<ul class="scope-list">${parts
      .map((p) => `<li>• ${escapeHtml(p)}</li>`)
      .join('')}</ul>`;
  }

  // No separators — return as paragraph
  return `<span>${escapeHtml(cleaned)}</span>`;
}

function escapeHtml(s: string): string {
  return String(s ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

function formatDate(d: string | undefined): string {
  if (!d) return '—';
  try {
    return new Date(d)
      .toLocaleDateString('en-GB', {
        day: '2-digit',
        month: 'short',
        year: 'numeric',
      })
      .replace(/ /g, '-');
  } catch {
    return d;
  }
}

// ✅ NEW — sanitize the company name into a safe filename stem
function safeFileName(s: string): string {
  return (s || 'scope-summary')
    .replace(/[^a-zA-Z0-9-_]/g, '_')
    .slice(0, 60);
}

export function generateScopeSummaryPDF(data: ScopeSummaryData): void {
  // ✅ Pick the logo based on client group
  const group = (data.clientGroup || '').toLowerCase().trim();
  const isTqs = group.includes('tqs');

  const absoluteLogoUrl = isTqs
    ? TQS_LOGO_URL // already absolute — do NOT prepend origin
    : typeof window !== 'undefined'
      ? `${window.location.origin}${LOGO_URL}` // QRS local logo
      : LOGO_URL;

  const standardsList =
    data.standards && data.standards.length > 0
      ? data.standards.map((s) => escapeHtml(s.name)).join(', ')
      : 'N/A';

  const stagesRows = data.stages
    .map((stage) => {
      const auditorName =
        stage.auditor?.firstName || stage.auditor?.lastName
          ? `${stage.auditor.firstName || ''} ${stage.auditor.lastName || ''}`.trim()
          : 'N/A';
      return `
        <tr>
          <td>${escapeHtml(stage.stageName)}</td>
          <td>${formatDate(stage.auditDate)}</td>
          <td>${escapeHtml(stage.anzicCode || '')}</td>
          <td>${escapeHtml(auditorName)}</td>
          <td>${escapeHtml(stage.technicalExpert || '')}</td>
        </tr>`;
    })
    .join('');

  // Validity checkboxes — based on company.validity field
  const validityValue = (data.company.validity || '').toLowerCase();
  const isYearly =
    validityValue.includes('1') ||
    validityValue.includes('year') ||
    validityValue.includes('surveillance');
  const isThreeYear = validityValue.includes('3');

  // ✅ NEW — used by the Word download to build the filename in the new window
  const fileNameStem = safeFileName(
    `${data.company.name || 'company'}_scope_summary`,
  );

  const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scope Summary Report — ${escapeHtml(data.company.name)}</title>
  <link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;600;700&display=swap" rel="stylesheet">
  <style>
    * { box-sizing: border-box; }
    html, body {
      margin: 0;
      padding: 0;
      font-family: 'Source Sans Pro', Arial, sans-serif;
      background-color: #f3f4f6;
      font-size: 12.5pt;
      font-weight: 400;
      color: #000;
    }

    /* Toolbar — visible on screen, hidden when printing */
    .toolbar {
      position: sticky;
      top: 0;
      z-index: 100;
      background: linear-gradient(135deg, #1e3a8a 0%, #2d3e8e 100%);
      color: white;
      padding: 12px 24px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    }
    .toolbar-title {
      font-size: 14px;
      font-weight: 600;
      letter-spacing: 0.5px;
    }
    .toolbar-actions {
      display: flex;
      gap: 8px;
    }
    .toolbar-btn {
      padding: 8px 18px;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-size: 13px;
      font-weight: 600;
      transition: all 0.15s;
    }
    .btn-primary {
      background: white;
      color: #1e3a8a;
    }
    .btn-primary:hover {
      background: #f1f5f9;
      transform: translateY(-1px);
    }
    .btn-word {
      background: #2563eb;
      color: white;
    }
    .btn-word:hover {
      background: #1d4ed8;
      transform: translateY(-1px);
    }
    .btn-word:disabled {
      background: #93c5fd;
      cursor: wait;
    }
    .btn-secondary {
      background: rgba(255,255,255,0.15);
      color: white;
      border: 1px solid rgba(255,255,255,0.3);
    }
    .btn-secondary:hover {
      background: rgba(255,255,255,0.25);
    }

    /* Page wrapper */
    .page-wrapper {
      max-width: 210mm;
      margin: 20px auto;
      background: white;
      padding: 6px;
      box-shadow: 0 4px 16px rgba(0,0,0,0.1);
    }

    .page-border {
      border: 3px solid #2d3e8e;
      padding: 2px;
      min-height: 287mm;
      box-sizing: border-box;
    }

    .inner-border {
      border: 1px solid #2d3e8e;
      min-height: 100%;
      padding: 6mm;
      box-sizing: border-box;
    }

    /* Header */
    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }

    .logo {
      width: 90px;
      height: 90px;
      object-fit: contain;
    }

    .title-box {
      padding: 6px 25px;
      font-weight: 700;
      text-transform: uppercase;
      font-size: 18px;
      text-align: center;
      letter-spacing: 1px;
    }

    .empty-box {
      border: 1px solid #c10808;
      padding: 8px 14px;
      font-size: 12px;
      font-weight: 600;
      text-align: left;
      min-width: 160px;
      line-height: 1.5;
    }

    .empty-box .job-code {
      font-weight: 500;
    }

    /* Tables */
    table {
      width: 100%;
      border-collapse: collapse;
      font-size: 13px;
      margin-top: 5px;
    }

    th {
      border: 1.6px solid black;
      padding: 6px 8px;
      font-weight: 600;
      color: black;
      background-color: #fafafa;
    }

    td {
      border: 1.6px solid black;
      padding: 6px 8px;
      font-weight: 400;
      color: #333333;
      vertical-align: top;
    }

    td strong {
      font-weight: 600;
      color: #000;
    }

    /* Section title */
    .section-title {
      font-size: 13px;
      font-weight: 600;
      margin-top: 18px;
      margin-bottom: 5px;
    }

    /* Scope of work paragraph */
    .scope-text {
      margin: 0 0 10px 0;
      line-height: 1.5;
      font-size: 13px;
    }

    .scope-list {
      list-style: none;
      padding-left: 0;
      margin: 0 0 10px 0;
    }

    .scope-list li {
      margin: 5px 0;
      line-height: 1.4;
      font-size: 13px;
    }

    /* Remarks box */
    .remarks {
      height: 100px;
      border: 1.6px solid black;
      margin-top: 5px;
      font-size: 12px;
      padding: 6px;
      white-space: pre-wrap;
    }

    /* Footer */
    .footer {
      text-align: center;
      font-size: 10pt;
      margin-top: 15px;
      padding-top: 10px;
    }

    /* ✅ FIXED — Print styles
       Old version: content shrunk into a small box at the top of the page with
       massive empty space below, because @page margin:0 + .page-border min-height:287mm
       overflowed the printable area and browsers compensated by scaling the whole
       layout down. New approach: give @page a SAFE printer margin, let the
       page-border fill that printable area naturally. */
    @media print {
      html, body {
        background: white !important;
        margin: 0 !important;
        padding: 0 !important;
        width: 100%;
        height: auto;
      }
      .toolbar { display: none !important; }
      .page-wrapper {
        margin: 0 !important;
        padding: 0 !important;
        box-shadow: none !important;
        max-width: 100% !important;
        width: 100% !important;
        background: white !important;
      }
      .page-border {
        border: 3px solid #2d3e8e !important;
        padding: 2px !important;
        min-height: auto !important;   /* ✅ stop forcing 287mm — let content size itself */
        margin: 0 !important;
      }
      .inner-border {
        border: 1px solid #2d3e8e !important;
        padding: 4mm !important;
        min-height: auto !important;   /* ✅ same */
      }
      /* ✅ Use a SAFE printer margin (0.4in / ~10mm) all around.
         Most printers can't print closer to the edge than this, so margin:0
         caused the borders to be clipped or the content to shrink. */
      @page {
        margin: 0.4in 0.4in 0.4in 0.4in;
        size: A4 portrait;
      }
      /* Avoid awkward page breaks inside tables/cells */
      table { page-break-inside: avoid; }
      tr    { page-break-inside: avoid; }
      .header { page-break-after: avoid; }
      /* Force colors to actually print (Chrome/Edge default is to skip backgrounds) */
      * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
      }
    }
  </style>
</head>
<body>
  <!-- Toolbar (hidden on print) -->
  <div class="toolbar">
    <div class="toolbar-title">📄 SCOPE SUMMARY REPORT — ${escapeHtml(data.company.name)}</div>
    <div class="toolbar-actions">
      <button class="toolbar-btn btn-primary" onclick="window.print()">🖨 Print</button>
      <!-- ✅ NEW — Download Word button -->
      <button id="downloadWordBtn" class="toolbar-btn btn-word" onclick="downloadWord()">📄 Download Word</button>
      <button class="toolbar-btn btn-secondary" onclick="window.close()">✕ Close</button>
    </div>
  </div>

  <div class="page-wrapper" id="reportWrapper">
    <div class="page-border">
      <div class="inner-border">

        <!-- ─── HEADER ─── -->
        <div class="header">
          <img src="${absoluteLogoUrl}" class="logo" alt="logo" onerror="this.style.display='none'">
          <div class="title-box">SCOPE SUMMARY REPORT</div>
          <div class="empty-box">
            <strong>Job ID:</strong> ${escapeHtml(String(data.jobId ?? '—'))}<br>
            <strong>Job NO:</strong> <span class="job-code">${escapeHtml(data.jobCode || 'N/A')}</span>
          </div>
        </div>

        <!-- ─── MAIN DETAILS TABLE ─── -->
        <table>
          <tr>
            <td><strong>Company Name</strong></td>
            <td colspan="3">${escapeHtml(data.company.name || '—')}</td>
          </tr>
          <tr>
            <td><strong>Company Address</strong></td>
            <td colspan="3">${escapeHtml(data.company.address || '—')}</td>
          </tr>
          <tr>
            <td><strong>Contact Person</strong></td>
            <td>${escapeHtml(data.company.contact_person || '—')}</td>
            <td><strong>Designation</strong></td>
            <td>${escapeHtml(data.company.designation || '—')}</td>
          </tr>
          <tr>
            <td><strong>Email Address</strong></td>
            <td>${escapeHtml(data.company.email || '—')}</td>
            <td><strong>Mobile No.</strong></td>
            <td>${escapeHtml(data.company.mobile || '—')}</td>
          </tr>
          <tr>
            <td><strong>Telephone</strong></td>
            <td>${escapeHtml(data.company.telephone || '—')}</td>
            <td><strong>Fax No.</strong></td>
            <td>${escapeHtml(data.company.fax || '—')}</td>
          </tr>
          <tr>
            <td><strong>STANDARDS</strong></td>
            <td>${standardsList}</td>
            <td><strong>Validity</strong></td>
            <td>
              ${isYearly ? '☑' : '□'} yearly surveillance<br>
              ${isThreeYear ? '☑' : '□'} 3 years
            </td>
          </tr>
          <tr>
            <td><strong>Certification Body</strong></td>
            <td>${escapeHtml(data.company.certification_body || '—')}</td>
            <td><strong>Accreditation</strong></td>
            <td>${escapeHtml(data.company.accreditation || '—')}</td>
          </tr>
        </table>

        <!-- ─── SCOPE OF WORK ─── -->
        <div class="section-title">Scope of Work:</div>
        <div class="scope-text">${formatScopeText(data.company.scope_of_work)}</div>

        <!-- ─── STAGES TABLE ─── -->
        <table>
          <tr>
            <th></th>
            <th>Audit Date</th>
            <th>ANZIC Code</th>
            <th>Auditor</th>
            <th>Technical Expert</th>
          </tr>
          ${stagesRows || '<tr><td colspan="5" style="text-align:center; color:#999;">No stages selected</td></tr>'}
        </table>

        <!-- ─── REMARKS ─── -->
        <div class="section-title">Remarks:</div>
        <div class="remarks">${escapeHtml(data.remarks || '')}</div>

        <!-- ─── FOOTER ─── -->
        <div class="footer">
          P.O. BOX 26826 Abu Dhabi, UAE, Tel No.: +971-26712161, Fax No.: +971-2-6713982
        </div>

      </div>
    </div>
  </div>

  <!-- ✅ NEW — Word download script.
       v4 (this version):
       - Tight margins (0.3in all around) so Word output fits the page like the PDF
       - Page borders + inner border tightened to use less padding
       - All other styling preserved -->
  <script>
    // Convert image URL to a base64 data URI so it gets embedded in the .doc file
    function imageToDataUrl(url) {
      return new Promise(function (resolve) {
        try {
          var img = new Image();
          img.crossOrigin = 'anonymous';
          img.onload = function () {
            try {
              var canvas = document.createElement('canvas');
              canvas.width = img.naturalWidth;
              canvas.height = img.naturalHeight;
              var ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              resolve(canvas.toDataURL('image/png'));
            } catch (e) {
              resolve(url); // fall back if canvas is tainted
            }
          };
          img.onerror = function () { resolve(url); };
          img.src = url;
        } catch (e) {
          resolve(url);
        }
      });
    }

    function applyStyle(el, styles) {
      if (!el) return;
      Object.keys(styles).forEach(function (k) {
        el.style[k] = styles[k];
      });
    }

    async function downloadWord() {
      var btn = document.getElementById('downloadWordBtn');
      btn.disabled = true;
      var originalText = btn.innerHTML;
      btn.innerHTML = '⏳ Building Word file...';

      try {
        var reportEl = document.getElementById('reportWrapper');
        if (!reportEl) throw new Error('Report content not found');

        var clone = reportEl.cloneNode(true);

        // 1. Embed the logo as base64
        var logoImg = clone.querySelector('img.logo');
        if (logoImg) {
          var dataUrl = await imageToDataUrl(logoImg.src);
          logoImg.setAttribute('src', dataUrl);
          logoImg.setAttribute('width', '90');
          logoImg.setAttribute('height', '90');
          applyStyle(logoImg, { width: '90px', height: '90px', display: 'block' });
        }

        // 2. Replace flex .header with a real <table>
        var header = clone.querySelector('.header');
        if (header) {
          var logoEl = header.querySelector('.logo') || header.children[0];
          var titleEl = header.querySelector('.title-box');
          var jobEl = header.querySelector('.empty-box');

          var headerTable = document.createElement('table');
          applyStyle(headerTable, {
            width: '100%',
            borderCollapse: 'collapse',
            border: '0',
            marginBottom: '10px',
          });
          headerTable.setAttribute('cellpadding', '0');
          headerTable.setAttribute('cellspacing', '0');
          headerTable.setAttribute('border', '0');

          var hRow = document.createElement('tr');

          var c1 = document.createElement('td');
          applyStyle(c1, {
            border: '0',
            verticalAlign: 'middle',
            padding: '2px',
            width: '100px',
          });
          if (logoEl) c1.appendChild(logoEl);

          var c2 = document.createElement('td');
          applyStyle(c2, {
            border: '0',
            verticalAlign: 'middle',
            padding: '2px',
            textAlign: 'center',
          });
          if (titleEl) c2.appendChild(titleEl);

          var c3 = document.createElement('td');
          applyStyle(c3, {
            border: '0',
            verticalAlign: 'middle',
            padding: '2px',
            width: '180px',
            textAlign: 'right',
          });
          if (jobEl) c3.appendChild(jobEl);

          hRow.appendChild(c1);
          hRow.appendChild(c2);
          hRow.appendChild(c3);
          headerTable.appendChild(hRow);

          header.parentNode.replaceChild(headerTable, header);
        }

        // 3. Walk all <td> in DATA tables (skip header table cells)
        clone.querySelectorAll('table td').forEach(function (td) {
          if (td.style.border === '0px' || td.getAttribute('style')?.indexOf('border: 0') > -1) return;
          applyStyle(td, {
            border: '1.6px solid black',
            padding: '6px 8px',
            verticalAlign: 'top',
            fontFamily: 'Arial, sans-serif',
            fontSize: '13px',
            fontWeight: '400',
            color: '#333333',
          });
        });

        // 4. <th>
        clone.querySelectorAll('th').forEach(function (th) {
          applyStyle(th, {
            border: '1.6px solid black',
            padding: '6px 8px',
            backgroundColor: '#fafafa',
            fontFamily: 'Arial, sans-serif',
            fontSize: '13px',
            fontWeight: '600',
            color: '#000',
          });
        });

        // 5. <strong> — only the labels stay bold
        clone.querySelectorAll('strong').forEach(function (s) {
          applyStyle(s, {
            fontWeight: '600',
            color: '#000',
          });
        });

        // 6. Header pieces
        var titleBox = clone.querySelector('.title-box');
        if (titleBox) {
          applyStyle(titleBox, {
            fontWeight: '700',
            fontSize: '18px',
            textAlign: 'center',
            textTransform: 'uppercase',
            letterSpacing: '1px',
            fontFamily: 'Arial, sans-serif',
          });
        }
        var emptyBox = clone.querySelector('.empty-box');
        if (emptyBox) {
          applyStyle(emptyBox, {
            border: '1px solid #c10808',
            padding: '8px 14px',
            fontSize: '12px',
            fontWeight: '600',
            lineHeight: '1.5',
            fontFamily: 'Arial, sans-serif',
            display: 'inline-block',
          });
        }

        // 7. Section titles
        clone.querySelectorAll('.section-title').forEach(function (st) {
          applyStyle(st, {
            fontSize: '13px',
            fontWeight: '600',
            marginTop: '18px',
            marginBottom: '5px',
            color: '#000',
            fontFamily: 'Arial, sans-serif',
          });
        });

        // 8. Scope text + list
        var scopeText = clone.querySelector('.scope-text');
        if (scopeText) {
          applyStyle(scopeText, {
            margin: '0 0 10px 0',
            lineHeight: '1.5',
            fontSize: '13px',
            fontWeight: '400',
            fontFamily: 'Arial, sans-serif',
            color: '#000',
          });
        }
        clone.querySelectorAll('.scope-list').forEach(function (ul) {
          applyStyle(ul, {
            listStyle: 'none',
            paddingLeft: '0',
            margin: '0 0 10px 0',
          });
        });
        clone.querySelectorAll('.scope-list li').forEach(function (li) {
          applyStyle(li, {
            margin: '5px 0',
            lineHeight: '1.4',
            fontSize: '13px',
            fontWeight: '400',
            fontFamily: 'Arial, sans-serif',
            color: '#000',
          });
        });

        // 9. Remarks
        var remarks = clone.querySelector('.remarks');
        if (remarks) {
          applyStyle(remarks, {
            height: '100px',
            border: '1.6px solid black',
            padding: '6px',
            fontSize: '12px',
            fontWeight: '400',
            fontFamily: 'Arial, sans-serif',
            color: '#000',
            whiteSpace: 'pre-wrap',
          });
        }

        // 10. Footer
        var footer = clone.querySelector('.footer');
        if (footer) {
          applyStyle(footer, {
            textAlign: 'center',
            fontSize: '10pt',
            marginTop: '15px',
            paddingTop: '10px',
            fontWeight: '400',
            fontFamily: 'Arial, sans-serif',
            color: '#000',
          });
        }

        // 11. Tables
        clone.querySelectorAll('table').forEach(function (t) {
          if (t.getAttribute('border') === '0') return;
          applyStyle(t, {
            width: '100%',
            borderCollapse: 'collapse',
            marginTop: '5px',
            fontFamily: 'Arial, sans-serif',
            fontSize: '13px',
          });
        });

        // ✅ 12. Page borders — TIGHTER padding so layout matches the PDF
        var pageBorder = clone.querySelector('.page-border');
        if (pageBorder) {
          applyStyle(pageBorder, {
            border: '3px solid #2d3e8e',
            padding: '3px',          // was 6px — tighter
            margin: '0',
          });
        }
        var innerBorder = clone.querySelector('.inner-border');
        if (innerBorder) {
          applyStyle(innerBorder, {
            border: '1px solid #2d3e8e',
            padding: '8px',          // was 12px — tighter
            margin: '0',
          });
        }
        // Also tighten the wrapper itself
        applyStyle(clone, {
          margin: '0',
          padding: '0',
          maxWidth: '100%',
          boxShadow: 'none',
        });

        // ─── 13. Build Word HTML envelope with TIGHT page margins ───
        // PDF uses @page margin:0. Word can't truly do 0 margins (printer drivers complain),
        // so we use 0.3in which is the practical minimum and matches the PDF look.
        var head =
          '<html xmlns:o="urn:schemas-microsoft-com:office:office" ' +
          'xmlns:w="urn:schemas-microsoft-com:office:word" ' +
          'xmlns="http://www.w3.org/TR/REC-html40">' +
          '<head><meta charset="utf-8">' +
          '<title>Scope Summary Report</title>' +
          // ✅ Word-specific page setup — sets ALL FOUR margins to a tight value (0.3in ≈ 7.6mm)
          // Word reads these w:sectPr properties from the WordDocument XML block.
          '<!--[if gte mso 9]><xml>' +
          '<w:WordDocument>' +
          '<w:View>Print</w:View>' +
          '<w:Zoom>100</w:Zoom>' +
          '<w:DoNotOptimizeForBrowser/>' +
          '</w:WordDocument>' +
          '<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true">' +
          '</w:LatentStyles>' +
          '</xml><![endif]-->' +
          '<style>' +
          // ✅ TIGHT MARGINS — 0.3in all around (matches PDF zero-margin look)
          '@page { size: A4; margin: 0.3in 0.3in 0.3in 0.3in; mso-page-orientation: portrait; }' +
          '@page Section1 { size: A4; margin: 0.3in 0.3in 0.3in 0.3in; mso-header-margin: 0in; mso-footer-margin: 0in; }' +
          'div.Section1 { page: Section1; }' +
          'body { font-family: Arial, sans-serif; font-size: 12.5pt; color: #000; font-weight: 400; margin: 0; padding: 0; }' +
          '</style></head><body><div class="Section1">';

        var foot = '</div></body></html>';
        var content = head + clone.innerHTML + foot;

        var blob = new Blob(['\\ufeff', content], {
          type: 'application/msword',
        });

        var fileName = '${fileNameStem}.doc';
        var link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        setTimeout(function () { URL.revokeObjectURL(link.href); }, 1000);

        btn.innerHTML = '✓ Downloaded';
        setTimeout(function () {
          btn.innerHTML = originalText;
          btn.disabled = false;
        }, 1500);
      } catch (err) {
        console.error('Word download failed:', err);
        alert('Failed to generate Word file: ' + (err.message || err));
        btn.innerHTML = originalText;
        btn.disabled = false;
      }
    }
  </script>
</body>
</html>`;

  const win = window.open('', '_blank');
  if (!win) {
    alert('Popup blocked. Please allow popups for this site.');
    return;
  }
  win.document.open();
  win.document.write(html);
  win.document.close();
}