// components/_gaokao-export-block.jsx — Wave 17-A
// 志愿表导出 block: CSV (海南考试院格式) + 打印正式志愿表 + 预览 table
//
// Props:
//   slots    — Array of up to 30 slot objects:
//              { schoolCode, schoolName, majorGroupCode, majorCode, majorName, acceptAdjust? }
//   userInfo — { name, examId, score, rank, subjectCombo }
//   batch    — string, e.g. '本科批'
//   lang     — 'zh' | 'en'
//
// Exposes window.GaokaoExportBlock.

const GaokaoExportBlock = ({ slots = [], userInfo = {}, batch = '本科批', lang = 'zh' }) => {
  const [open, setOpen] = React.useState(false);

  // ── i18n dict ────────────────────────────────────────────────────────────────
  const dict = React.useMemo(() => {
    const base = (window.I18N && window.I18N[lang] && window.I18N[lang].gk && window.I18N[lang].gk.export) || {};
    return {
      chip:          base.chip          || (lang === 'zh' ? '📋 导出志愿表' : '📋 Export Form'),
      modalTitle:    base.modalTitle    || (lang === 'zh' ? '导出志愿表' : 'Export Application Form'),
      modalSubtitle: base.modalSubtitle || (lang === 'zh' ? '海南考试院格式 CSV + 打印正式志愿表' : 'Hainan Exam Bureau CSV + Printable form'),
      csvBtn:        base.csvBtn        || (lang === 'zh' ? '下载海南考试院 CSV' : 'Download Hainan CSV'),
      printBtn:      base.printBtn      || (lang === 'zh' ? '打印正式志愿表' : 'Print Official Form'),
      previewTitle:  base.previewTitle  || (lang === 'zh' ? '志愿预览（30 槽）' : 'Slot Preview (30)'),
      close:         base.close         || (lang === 'zh' ? '关闭' : 'Close'),
      colSeq:        base.colSeq        || (lang === 'zh' ? '序号' : '#'),
      colSchCode:    base.colSchCode    || (lang === 'zh' ? '院校代码' : 'School Code'),
      colSchName:    base.colSchName    || (lang === 'zh' ? '院校名称' : 'School Name'),
      colGrpCode:    base.colGrpCode    || (lang === 'zh' ? '专业组代码' : 'Group Code'),
      colMajCode:    base.colMajCode    || (lang === 'zh' ? '专业代码' : 'Major Code'),
      colMajName:    base.colMajName    || (lang === 'zh' ? '专业名称' : 'Major Name'),
      colAdjust:     base.colAdjust     || (lang === 'zh' ? '服从调剂' : 'Accept Adjust'),
      emptySlot:     base.emptySlot     || (lang === 'zh' ? '（未填）' : '(empty)'),
      csvHint:       base.csvHint       || (lang === 'zh' ? '将 CSV 文件导入海南省招生考试局官方系统' : 'Import into the Hainan Exam Bureau official system'),
      printHint:     base.printHint     || (lang === 'zh' ? '适合打印存档或交给顾问审核' : 'For print archiving or counselor review'),
      filledCount:   base.filledCount   || ((n) => lang === 'zh' ? `已填 ${n} / 30 志愿` : `${n}/30 slots filled`),
      majorCodeWarning: base.majorCodeWarning || ((n) => lang === 'zh'
        ? `⚠ 本表的专业代码为系统内部占位或尚未对应到正式代号（共 ${n} 项），不能直接用于海南填报系统。导入或填报前，请对照官方《海南省普通高校招生专业目录》确认每个专业的正式代号，以官方为准。`
        : `⚠ ${n} major code(s) here are internal placeholders or not yet mapped to official codes — not directly usable in the Hainan application system. Verify each against the official Hainan major catalog before importing or submitting.`),
    };
  }, [lang]);

  // ── ESC + body-scroll-lock while modal open ────────────────────────────────
  React.useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = prev;
      window.removeEventListener('keydown', onKey);
    };
  }, [open]);

  // ── Resolve formatter ──────────────────────────────────────────────────────
  // In browser context the lib isn't require()-able, so we expect it to be
  // exposed on window (added via a <script> tag in Node/test environments).
  // In e2e tests we inline a minimal stub via page.evaluate() if needed.
  const getFormatter = () => {
    if (window.GaokaoExportFormatter) return window.GaokaoExportFormatter;
    // Lightweight inline fallback so the buttons always work even without the lib script
    return {
      exportToHainanCsv: ({ slots: s = [], userInfo: u = {}, batch: b = '本科批' } = {}) => {
        const header = '序号,院校代码,院校名称,专业组代码,专业代码,专业名称,是否服从调剂';
        const rows = Array.from({ length: 30 }, (_, i) => {
          const slot = s[i] || {};
          const esc = (v) => {
            const str = String(v == null ? '' : v);
            return (str.includes(',') || str.includes('"')) ? '"' + str.replace(/"/g, '""') + '"' : str;
          };
          return [
            i + 1,
            esc(slot.schoolCode || ''),
            esc(slot.schoolName || ''),
            esc(slot.majorGroupCode || ''),
            esc(slot.majorCode || ''),
            esc(slot.majorName || ''),
            slot.schoolCode ? (slot.acceptAdjust === false ? '否' : '是') : '',
          ].join(',');
        });
        return '﻿# 海南省志愿表\r\n' + header + '\r\n' + rows.join('\r\n') + '\r\n';
      },
      exportToPrintableHtml: ({ slots: s = [], userInfo: u = {}, batch: b = '本科批' } = {}) => {
        const rows = Array.from({ length: 30 }, (_, i) => {
          const slot = s[i] || {};
          return `<tr><td>${i + 1}</td><td>${slot.schoolCode || ''}</td><td>${slot.schoolName || ''}</td><td>${slot.majorGroupCode || ''}</td><td>${slot.majorCode || ''}</td><td>${slot.majorName || ''}</td><td>${slot.schoolCode ? (slot.acceptAdjust === false ? '否' : '是') : ''}</td></tr>`;
        }).join('');
        return `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>志愿表</title></head><body><h1>海南省高考志愿表</h1><p>${b}</p><table border="1"><tr><th>序号</th><th>院校代码</th><th>院校名称</th><th>专业组代码</th><th>专业代码</th><th>专业名称</th><th>是否服从调剂</th></tr>${rows}</table></body></html>`;
      },
    };
  };

  // ── CSV download ───────────────────────────────────────────────────────────
  const handleDownloadCsv = () => {
    const fmt = getFormatter();
    const csv = fmt.exportToHainanCsv({ slots, userInfo, batch });
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `志愿表_${userInfo.name || '考生'}_${batch}_${Date.now()}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  // ── Print ──────────────────────────────────────────────────────────────────
  const handlePrint = () => {
    const fmt = getFormatter();
    const html = fmt.exportToPrintableHtml({ slots, userInfo, batch });
    const win = window.open('', '_blank', 'width=900,height=700');
    if (!win) return; // popup blocked
    win.document.open();
    win.document.write(html);
    win.document.close();
    win.focus();
    // Small delay to ensure styles render before print dialog
    setTimeout(() => { win.print(); }, 400);
  };

  const filledCount = slots.filter((s) => s && s.schoolCode).length;
  // D5/D6 (#259) — ~99% of HI majorCodes are internal `ord-NN` placeholders, not
  // the official Hainan application codes. Count filled slots whose major code is
  // a placeholder (or empty) so we can warn before the user fills the official portal.
  const placeholderCodeCount = slots.filter(
    (s) => s && s.schoolCode && (!s.majorCode || /^ord-/i.test(String(s.majorCode)))
  ).length;

  // ── Styles ─────────────────────────────────────────────────────────────────
  const chipStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: 6,
    padding: '6px 14px',
    fontSize: 12,
    fontWeight: 600,
    letterSpacing: '0.04em',
    borderRadius: 100,
    border: '1px solid var(--pb-gold-500)',
    background: 'transparent',
    color: 'var(--pb-gold-700, #a07830)',
    cursor: 'pointer',
    transition: 'background 0.15s, color 0.15s',
  };

  const actionBtnBase = {
    display: 'flex',
    alignItems: 'center',
    gap: 8,
    padding: '12px 20px',
    fontSize: 14,
    fontWeight: 600,
    borderRadius: 8,
    cursor: 'pointer',
    border: 'none',
    transition: 'opacity 0.15s',
    width: '100%',
    justifyContent: 'flex-start',
  };

  const thStyle = {
    padding: '8px 10px',
    fontSize: 11,
    fontWeight: 700,
    textTransform: 'uppercase',
    letterSpacing: '0.06em',
    background: 'var(--pb-navy-900, #0a1628)',
    color: '#fff',
    borderBottom: '2px solid var(--pb-border, #e0e0e0)',
    whiteSpace: 'nowrap',
    textAlign: 'center',
  };

  const tdBase = {
    padding: '6px 10px',
    fontSize: 12,
    borderBottom: '1px solid var(--pb-border, #e8e8e8)',
    verticalAlign: 'middle',
  };

  return (
    <React.Fragment>
      {/* ── Export chip ─────────────────────────────────────────────────── */}
      <button
        type="button"
        data-testid="export-block-chip"
        onClick={() => setOpen(true)}
        style={chipStyle}
        onMouseEnter={(e) => {
          e.currentTarget.style.background = 'var(--pb-gold-500, #c9a96e)';
          e.currentTarget.style.color = 'var(--pb-navy-900, #0a1628)';
        }}
        onMouseLeave={(e) => {
          e.currentTarget.style.background = 'transparent';
          e.currentTarget.style.color = 'var(--pb-gold-700, #a07830)';
        }}
      >
        {dict.chip}
      </button>

      {/* ── Modal ───────────────────────────────────────────────────────── */}
      {open && (
        <div
          role="dialog"
          aria-modal="true"
          aria-labelledby="gaokao-export-modal-title"
          data-testid="export-modal"
          style={{
            position: 'fixed',
            inset: 0,
            // Unified top modal layer — above auth-gate (2147483640) & tweaks panel (2147483646) so the popover is never occluded (#258/#218).
            zIndex: 2147483647,
            background: 'rgba(10, 22, 40, 0.6)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: 24,
          }}
          onClick={(e) => { if (e.target === e.currentTarget) setOpen(false); }}
        >
          <div
            className="pb-card"
            style={{
              maxWidth: 820,
              width: '100%',
              maxHeight: '90vh',
              overflow: 'auto',
              padding: 0,
              boxShadow: '0 24px 64px rgba(0,0,0,0.4)',
            }}
            onClick={(e) => e.stopPropagation()}
          >
            {/* Modal header */}
            <div
              style={{
                padding: '22px 28px',
                borderBottom: '1px solid var(--pb-border, #e0e0e0)',
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'flex-start',
                gap: 16,
                position: 'sticky',
                top: 0,
                background: 'var(--pb-paper, #f8f7f4)',
                zIndex: 1,
              }}
            >
              <div>
                <div className="pb-eyebrow" style={{ color: 'var(--pb-gold-700, #a07830)', marginBottom: 6 }}>
                  {lang === 'zh' ? '志愿表导出 · WAVE 17-A' : 'Application Form Export · WAVE 17-A'}
                </div>
                <h3
                  id="gaokao-export-modal-title"
                  style={{ fontFamily: 'var(--pb-serif)', fontSize: 20, fontWeight: 700, margin: 0 }}
                >
                  {dict.modalTitle}
                </h3>
                <p style={{ fontSize: 12, color: 'var(--pb-fg-muted, #888)', margin: '4px 0 0', lineHeight: 1.5 }}>
                  {dict.modalSubtitle} · <strong>{typeof dict.filledCount === 'function' ? dict.filledCount(filledCount) : filledCount + '/30'}</strong>
                </p>
              </div>
              <button
                type="button"
                aria-label={dict.close}
                onClick={() => setOpen(false)}
                style={{
                  background: 'transparent',
                  border: '1px solid var(--pb-border, #e0e0e0)',
                  borderRadius: 8,
                  padding: '4px 10px',
                  fontSize: 16,
                  lineHeight: 1,
                  cursor: 'pointer',
                  color: 'var(--pb-fg-muted, #888)',
                  flexShrink: 0,
                }}
              >
                ×
              </button>
            </div>

            {/* D5/D6 (#259) — non-official major-code warning */}
            {placeholderCodeCount > 0 && (
              <div
                data-testid="export-majorcode-warning"
                role="alert"
                style={{
                  margin: '16px 28px 0',
                  padding: '10px 14px',
                  background: 'rgba(217,164,6,0.10)',
                  border: '1px solid rgba(217,164,6,0.45)',
                  borderRadius: 8,
                  color: 'var(--pb-fg, #3a3120)',
                  fontSize: 12.5,
                  lineHeight: 1.6,
                }}
              >
                {typeof dict.majorCodeWarning === 'function' ? dict.majorCodeWarning(placeholderCodeCount) : dict.majorCodeWarning}
              </div>
            )}

            {/* Action buttons */}
            <div
              style={{
                display: 'grid',
                gridTemplateColumns: '1fr 1fr',
                gap: 16,
                padding: '20px 28px',
                borderBottom: '1px solid var(--pb-border, #e0e0e0)',
              }}
            >
              {/* CSV download */}
              <div
                style={{
                  border: '1px solid var(--pb-border, #e0e0e0)',
                  borderRadius: 10,
                  padding: 16,
                  background: 'var(--pb-surface-alt, #f4f3f0)',
                }}
              >
                <button
                  type="button"
                  data-testid="export-csv-btn"
                  onClick={handleDownloadCsv}
                  style={{
                    ...actionBtnBase,
                    background: 'var(--pb-navy-900, #0a1628)',
                    color: '#fff',
                    marginBottom: 8,
                  }}
                >
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                    <polyline points="7 10 12 15 17 10"/>
                    <line x1="12" y1="15" x2="12" y2="3"/>
                  </svg>
                  {dict.csvBtn}
                </button>
                <p style={{ fontSize: 11, color: 'var(--pb-fg-muted, #888)', margin: 0, lineHeight: 1.5 }}>
                  {dict.csvHint}
                </p>
              </div>

              {/* Print */}
              <div
                style={{
                  border: '1px solid var(--pb-border, #e0e0e0)',
                  borderRadius: 10,
                  padding: 16,
                  background: 'var(--pb-surface-alt, #f4f3f0)',
                }}
              >
                <button
                  type="button"
                  data-testid="export-print-btn"
                  onClick={handlePrint}
                  style={{
                    ...actionBtnBase,
                    background: 'var(--pb-gold-500, #c9a96e)',
                    color: 'var(--pb-navy-900, #0a1628)',
                    marginBottom: 8,
                  }}
                >
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <polyline points="6 9 6 2 18 2 18 9"/>
                    <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/>
                    <rect x="6" y="14" width="12" height="8"/>
                  </svg>
                  {dict.printBtn}
                </button>
                <p style={{ fontSize: 11, color: 'var(--pb-fg-muted, #888)', margin: 0, lineHeight: 1.5 }}>
                  {dict.printHint}
                </p>
              </div>
            </div>

            {/* Preview table */}
            <div style={{ padding: '16px 28px 24px' }}>
              <div
                style={{
                  fontSize: 12,
                  fontWeight: 700,
                  textTransform: 'uppercase',
                  letterSpacing: '0.08em',
                  color: 'var(--pb-fg-muted, #888)',
                  marginBottom: 10,
                }}
              >
                {dict.previewTitle}
              </div>
              <div style={{ overflowX: 'auto', border: '1px solid var(--pb-border, #e0e0e0)', borderRadius: 8 }}>
                <table
                  data-testid="export-preview-table"
                  style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}
                >
                  <thead>
                    <tr>
                      <th style={{ ...thStyle, width: 36 }}>{dict.colSeq}</th>
                      <th style={{ ...thStyle, width: 80 }}>{dict.colSchCode}</th>
                      <th style={{ ...thStyle, minWidth: 120 }}>{dict.colSchName}</th>
                      <th style={{ ...thStyle, width: 80 }}>{dict.colGrpCode}</th>
                      <th style={{ ...thStyle, width: 80 }}>{dict.colMajCode}</th>
                      <th style={{ ...thStyle, minWidth: 140 }}>{dict.colMajName}</th>
                      <th style={{ ...thStyle, width: 72 }}>{dict.colAdjust}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {Array.from({ length: 30 }, (_, i) => {
                      const slot = slots[i] || {};
                      const filled = !!slot.schoolCode;
                      const adjust = filled ? (slot.acceptAdjust === false ? '否' : '是') : '';
                      return (
                        <tr
                          key={i}
                          data-testid={`export-slot-row-${i}`}
                          style={{ background: i % 2 === 0 ? 'var(--pb-bg, #fff)' : 'var(--pb-surface-alt, #f4f3f0)' }}
                        >
                          <td style={{ ...tdBase, textAlign: 'center', color: 'var(--pb-fg-muted, #888)' }}>{i + 1}</td>
                          <td style={{ ...tdBase, textAlign: 'center', fontFamily: 'var(--pb-mono)', color: filled ? 'var(--pb-fg)' : 'var(--pb-fg-muted, #ccc)' }}>
                            {slot.schoolCode || '—'}
                          </td>
                          <td style={{ ...tdBase, fontWeight: filled ? 600 : 400, color: filled ? 'var(--pb-fg)' : 'var(--pb-fg-muted, #ccc)' }}>
                            {slot.schoolName || dict.emptySlot}
                          </td>
                          <td style={{ ...tdBase, textAlign: 'center', fontFamily: 'var(--pb-mono)', color: filled ? 'var(--pb-fg)' : 'var(--pb-fg-muted, #ccc)' }}>
                            {slot.majorGroupCode || '—'}
                          </td>
                          <td style={{ ...tdBase, textAlign: 'center', fontFamily: 'var(--pb-mono)', color: filled ? 'var(--pb-fg)' : 'var(--pb-fg-muted, #ccc)' }}>
                            {slot.majorCode || '—'}
                          </td>
                          <td style={{ ...tdBase, color: filled ? 'var(--pb-fg)' : 'var(--pb-fg-muted, #ccc)' }}>
                            {slot.majorName || '—'}
                          </td>
                          <td style={{ ...tdBase, textAlign: 'center', color: adjust === '否' ? 'var(--pb-danger, #e05252)' : 'var(--pb-success, #4caf74)' }}>
                            {adjust || '—'}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </div>

            {/* Modal footer */}
            <div
              style={{
                padding: '12px 28px',
                borderTop: '1px solid var(--pb-border, #e0e0e0)',
                background: 'var(--pb-surface-alt, #f4f3f0)',
                fontSize: 11,
                color: 'var(--pb-fg-muted, #888)',
                lineHeight: 1.6,
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
              }}
            >
              <span>
                {lang === 'zh'
                  ? '注：请以海南省招生考试局官方系统填报结果为准，本导出仅供辅助参考。'
                  : 'Note: Always confirm entries in the official Hainan Exam Bureau system. This export is for reference only.'}
              </span>
              <button
                type="button"
                onClick={() => setOpen(false)}
                style={{
                  background: 'transparent',
                  border: '1px solid var(--pb-border, #e0e0e0)',
                  borderRadius: 6,
                  padding: '5px 14px',
                  fontSize: 12,
                  cursor: 'pointer',
                  color: 'var(--pb-fg-muted, #888)',
                  flexShrink: 0,
                  marginLeft: 16,
                }}
              >
                {dict.close}
              </button>
            </div>
          </div>
        </div>
      )}
    </React.Fragment>
  );
};

window.GaokaoExportBlock = GaokaoExportBlock;
