// ─── Wave 13-B / M7 — ArtSportsMilitaryBlock ─────────────────────────────────
// Three chips: 🎨 艺术类 / ⚽ 体育类 / 🎖 军警类
// Each chip opens a modal listing the REAL 2025 海南本科提前批投档分数线 rows
// (per 院校专业组) for the corresponding dimension, loaded via
// window.fetch('/data/gaokao-{art|sports|military}/HI/2025.json').
//
// 诚实优先 (M7): data is the verified official 海南省考试局 2025 提前批 cutoff
// announcement. Each dimension carries its OWN scale (艺术/体育=综合分, 军警=900
// 标准分) — the modal shows the dimension's scale label + a 数据来源 line. No
// fabricated 招生人数 / 身高 / 性别比 (none exist in the official cutoff source).
//
// File shape (per dimension):
//   { province, year, dimension, scoreScale, scoreType, scaleNote,
//     subjectReqLegend, source:{url,title,publishedAt,type,publisher},
//     verifiedAt, rows:[ ... ] }
//
// No backend, no lib require (browser-side). Pure React + fetch.

const ArtSportsMilitaryBlock = ({ lang }) => {
  const [activeModal, setActiveModal] = React.useState(null); // 'art' | 'sports' | 'military' | null
  const [data, setData]               = React.useState({ art: null, sports: null, military: null });
  const [meta, setMeta]               = React.useState({ art: null, sports: null, military: null });
  const [loading, setLoading]         = React.useState({ art: false, sports: false, military: false });
  const [filterText, setFilterText]   = React.useState('');

  const zh = lang !== 'en';

  // i18n from window.I18N if available
  const t = (() => {
    const base = (window.I18N && window.I18N[lang] && window.I18N[lang].gk && window.I18N[lang].gk.artSportsMilitary) || {};
    const mt   = (base.modalTitle) || {};
    return {
      artChip:         base.chipArt      || (zh ? '🎨 艺术类' : '🎨 Art'),
      sportsChip:      base.chipSports   || (zh ? '⚽ 体育类' : '⚽ Sports'),
      militaryChip:    base.chipMilitary || (zh ? '🎖 军警类' : '🎖 Military/Police'),
      artTitle:        mt.art            || (zh ? '海南本科提前批 · 艺术类投档线' : 'HI Early Batch · Art Cutoffs'),
      sportsTitle:     mt.sports         || (zh ? '海南本科提前批 · 体育类投档线' : 'HI Early Batch · Sports Cutoffs'),
      militaryTitle:   mt.military       || (zh ? '海南本科提前批 · 军警类(须面试)投档线' : 'HI Early Batch · Military/Police Cutoffs'),
      artEyebrow:      base.artEyebrow      || (zh ? '艺术类 · 2025 海南本科提前批' : 'Art · HI 2025 Early Batch'),
      sportsEyebrow:   base.sportsEyebrow   || (zh ? '体育类 · 2025 海南本科提前批' : 'Sports · HI 2025 Early Batch'),
      militaryEyebrow: base.militaryEyebrow || (zh ? '军警类 · 2025 海南本科提前批(须面试)' : 'Military/Police · HI 2025 Early Batch'),
      close:           base.close        || (zh ? '关闭' : 'Close'),
      search:          base.search       || (zh ? '搜索院校/科类...' : 'Search school / category...'),
      noData:          base.noData       || (zh ? '暂无数据' : 'No data'),
      loading:         base.loading      || (zh ? '加载中...' : 'Loading...'),
      colSchool:       zh ? '院校(专业组)' : 'School (group)',
      colCategory:     zh ? '科类' : 'Category',
      colCutoff:       zh ? '投档线' : 'Cutoff',
      colSubj:         zh ? '选考科目' : 'Subj. req.',
      colMale:         zh ? '男生' : 'Male',
      colFemale:       zh ? '女生' : 'Female',
      sourceLabel:     zh ? '数据来源' : 'Source',
      verifiedLabel:   zh ? '已核验' : 'Verified',
    };
  })();

  // Modal config — points at the verified 2025 official files.
  const MODAL_CONFIG = {
    art:      { eyebrow: t.artEyebrow,      title: t.artTitle,      path: '/data/gaokao-art/HI/2025.json',      color: 'var(--pb-gold-500)', chipLabel: t.artChip,      testId: 'art-sports-military-chip-art' },
    sports:   { eyebrow: t.sportsEyebrow,   title: t.sportsTitle,   path: '/data/gaokao-sports/HI/2025.json',   color: '#4CAF50',             chipLabel: t.sportsChip,   testId: 'art-sports-military-chip-sports' },
    military: { eyebrow: t.militaryEyebrow, title: t.militaryTitle, path: '/data/gaokao-military/HI/2025.json', color: '#5C6BC0',             chipLabel: t.militaryChip, testId: 'art-sports-military-chip-military' },
  };

  const openModal = async (type) => {
    setActiveModal(type);
    setFilterText('');
    if (data[type] !== null) return; // already loaded
    setLoading((prev) => ({ ...prev, [type]: true }));
    try {
      const res = await fetch(MODAL_CONFIG[type].path);
      const json = res.ok ? await res.json() : null;
      // Verified files are objects with { rows, source, scoreScale, ... }.
      const rows = json && Array.isArray(json.rows) ? json.rows
        : (Array.isArray(json) ? json : []); // tolerate a bare array, but we ship objects
      setData((prev) => ({ ...prev, [type]: rows }));
      setMeta((prev) => ({ ...prev, [type]: (json && !Array.isArray(json)) ? json : null }));
    } catch (_e) {
      setData((prev) => ({ ...prev, [type]: [] }));
      setMeta((prev) => ({ ...prev, [type]: null }));
    } finally {
      setLoading((prev) => ({ ...prev, [type]: false }));
    }
  };

  const closeModal = () => { setActiveModal(null); setFilterText(''); };

  // Lock body scroll while modal open
  React.useEffect(() => {
    if (typeof document === 'undefined' || !document.body) return;
    if (!activeModal) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [activeModal]);

  // ESC to close
  React.useEffect(() => {
    if (!activeModal) return;
    const onKey = (e) => { if (e.key === 'Escape') closeModal(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [activeModal]);

  const chipStyle = (color) => ({
    display: 'inline-flex',
    alignItems: 'center',
    gap: 4,
    padding: '6px 14px',
    fontSize: 12,
    fontWeight: 600,
    letterSpacing: '0.03em',
    borderRadius: 100,
    border: `1px solid ${color}`,
    background: 'transparent',
    color: color,
    cursor: 'pointer',
    transition: 'background 0.15s, color 0.15s',
    whiteSpace: 'nowrap',
  });

  const currentRows = activeModal ? (data[activeModal] || []) : [];
  const currentMeta = activeModal ? meta[activeModal] : null;
  const filtered = filterText.trim()
    ? currentRows.filter((r) => {
        const q = filterText.toLowerCase();
        return (
          (r.schoolName || '').toLowerCase().includes(q) ||
          (r.groupName || '').toLowerCase().includes(q) ||
          (r.category || '').toLowerCase().includes(q)
        );
      })
    : currentRows;

  // ── Art / Sports row — same shape: { category, schoolName, groupName, cutoff, subjectReqCode } ──
  const renderCompositeRow = (entry, idx, accent) => (
    <div
      key={entry.groupCode || idx}
      data-testid={`${activeModal}-row-${idx}`}
      style={{ padding: '10px 20px', borderTop: idx === 0 ? 'none' : '1px solid var(--pb-border)', display: 'grid', gridTemplateColumns: '2.2fr 1.3fr 0.9fr 0.7fr', gap: 8, alignItems: 'center', fontSize: 13 }}
    >
      <div style={{ fontWeight: 600, fontSize: 13 }}>{entry.groupName || entry.schoolName}</div>
      <div style={{ color: 'var(--pb-fg-muted)', fontSize: 12 }}>{entry.category}</div>
      <div style={{ textAlign: 'right', fontWeight: 700, color: accent, fontVariantNumeric: 'tabular-nums' }}>{entry.cutoff}</div>
      <div style={{ textAlign: 'center', fontSize: 11, color: 'var(--pb-fg-muted)' }}>{entry.subjectReqCode}</div>
    </div>
  );

  // ── Military row — { schoolName, groupName, cutoffMale, cutoffFemale, subjectReqCode } ──
  const renderMilitaryRow = (entry, idx) => (
    <div
      key={entry.groupCode || idx}
      data-testid={`military-row-${idx}`}
      style={{ padding: '10px 20px', borderTop: idx === 0 ? 'none' : '1px solid var(--pb-border)', display: 'grid', gridTemplateColumns: '2.4fr 0.8fr 0.8fr 0.7fr', gap: 8, alignItems: 'center', fontSize: 13 }}
    >
      <div style={{ fontWeight: 600, fontSize: 13 }}>{entry.groupName || entry.schoolName}</div>
      <div style={{ textAlign: 'right', fontWeight: 700, color: '#5C6BC0', fontVariantNumeric: 'tabular-nums' }}>
        {entry.cutoffMale != null ? entry.cutoffMale : <span style={{ color: 'var(--pb-fg-muted)', fontWeight: 400 }}>—</span>}
      </div>
      <div style={{ textAlign: 'right', fontWeight: 700, color: '#5C6BC0', fontVariantNumeric: 'tabular-nums' }}>
        {entry.cutoffFemale != null ? entry.cutoffFemale : <span style={{ color: 'var(--pb-fg-muted)', fontWeight: 400 }}>—</span>}
      </div>
      <div style={{ textAlign: 'center', fontSize: 11, color: 'var(--pb-fg-muted)' }}>{entry.subjectReqCode}</div>
    </div>
  );

  const renderRow = (entry, idx) => {
    if (activeModal === 'art') return renderCompositeRow(entry, idx, 'var(--pb-gold-700)');
    if (activeModal === 'sports') return renderCompositeRow(entry, idx, '#2e7d32');
    if (activeModal === 'military') return renderMilitaryRow(entry, idx);
    return null;
  };

  const headerCellStyle = { fontSize: 11, color: 'var(--pb-fg-muted)', fontWeight: 600 };
  const renderHeader = () => {
    if (activeModal === 'art' || activeModal === 'sports') return (
      <div style={{ display: 'grid', gridTemplateColumns: '2.2fr 1.3fr 0.9fr 0.7fr', gap: 8, padding: '8px 20px', background: 'var(--pb-surface-alt)', borderBottom: '1px solid var(--pb-border)' }}>
        <div style={headerCellStyle}>{t.colSchool}</div>
        <div style={headerCellStyle}>{t.colCategory}</div>
        <div style={{ ...headerCellStyle, textAlign: 'right' }}>{t.colCutoff}</div>
        <div style={{ ...headerCellStyle, textAlign: 'center' }}>{t.colSubj}</div>
      </div>
    );
    if (activeModal === 'military') return (
      <div style={{ display: 'grid', gridTemplateColumns: '2.4fr 0.8fr 0.8fr 0.7fr', gap: 8, padding: '8px 20px', background: 'var(--pb-surface-alt)', borderBottom: '1px solid var(--pb-border)' }}>
        <div style={headerCellStyle}>{t.colSchool}</div>
        <div style={{ ...headerCellStyle, textAlign: 'right' }}>{t.colMale}</div>
        <div style={{ ...headerCellStyle, textAlign: 'right' }}>{t.colFemale}</div>
        <div style={{ ...headerCellStyle, textAlign: 'center' }}>{t.colSubj}</div>
      </div>
    );
    return null;
  };

  const cfg = activeModal ? MODAL_CONFIG[activeModal] : null;

  return (
    <React.Fragment>
      {/* ── Three chips ── */}
      {Object.entries(MODAL_CONFIG).map(([type, config]) => (
        <button
          key={type}
          type="button"
          data-testid={config.testId}
          onClick={() => openModal(type)}
          style={chipStyle(config.color)}
          onMouseEnter={(e) => { e.currentTarget.style.background = config.color; e.currentTarget.style.color = '#fff'; }}
          onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = config.color; }}
        >
          {config.chipLabel}
        </button>
      ))}

      {/* ── Modal — portalled to body to escape sticky stacking context (#258) ── */}
      {activeModal && ReactDOM.createPortal(
        <div
          data-testid="art-sports-military-modal"
          role="dialog"
          aria-modal="true"
          aria-labelledby="asm-modal-title"
          style={{ position: 'fixed', inset: 0, zIndex: 2147483647, background: 'rgba(15, 22, 36, 0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}
          onClick={(e) => { if (e.target === e.currentTarget) closeModal(); }}
        >
          <div
            className="pb-card"
            style={{ maxWidth: 780, width: '100%', maxHeight: '88vh', overflow: 'auto', padding: 0, boxShadow: '0 20px 60px rgba(0,0,0,0.35)', display: 'flex', flexDirection: 'column' }}
          >
            {/* Header */}
            <div style={{ padding: '20px 24px', borderBottom: '1px solid var(--pb-border)', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16, position: 'sticky', top: 0, background: 'var(--pb-paper)', zIndex: 1 }}>
              <div style={{ flex: 1 }}>
                <div className="pb-eyebrow" style={{ color: cfg.color, marginBottom: 6 }}>{cfg.eyebrow}</div>
                <h3 id="asm-modal-title" style={{ fontFamily: 'var(--pb-serif)', fontSize: 20, fontWeight: 600, margin: '0 0 6px' }}>
                  {cfg.title}
                </h3>
                {/* Scale label — each dimension's own unit, stated honestly */}
                {currentMeta && currentMeta.scoreScale && (
                  <div data-testid="asm-scale-label" style={{ fontSize: 12, color: 'var(--pb-fg-muted)', marginBottom: 8 }}>
                    {zh ? '投档线口径：' : 'Cutoff scale: '}
                    <strong style={{ color: cfg.color }}>{currentMeta.scoreScale}</strong>
                    {currentMeta.scaleNote && <span> · {currentMeta.scaleNote}</span>}
                  </div>
                )}
                {/* Search */}
                <input
                  type="text"
                  placeholder={t.search}
                  value={filterText}
                  onChange={(e) => setFilterText(e.target.value)}
                  data-testid="art-sports-military-search"
                  style={{ width: '100%', maxWidth: 320, padding: '6px 10px', fontSize: 12, borderRadius: 6, border: '1px solid var(--pb-border)', background: 'var(--pb-surface-alt)', color: 'var(--pb-fg)', outline: 'none', boxSizing: 'border-box' }}
                />
              </div>
              <button
                type="button"
                data-testid="art-sports-military-close"
                aria-label={t.close}
                onClick={closeModal}
                style={{ background: 'transparent', border: '1px solid var(--pb-border)', borderRadius: 8, padding: '4px 10px', fontSize: 16, lineHeight: 1, cursor: 'pointer', color: 'var(--pb-fg-muted)', flexShrink: 0 }}
              >
                ×
              </button>
            </div>

            {/* Column headers */}
            {!loading[activeModal] && renderHeader()}

            {/* Body */}
            <div style={{ flex: 1, overflow: 'auto' }}>
              {loading[activeModal] && (
                <div style={{ padding: 40, textAlign: 'center', color: 'var(--pb-fg-muted)', fontSize: 13 }}>{t.loading}</div>
              )}
              {!loading[activeModal] && filtered.length === 0 && (
                <div style={{ padding: 40, textAlign: 'center', color: 'var(--pb-fg-muted)', fontSize: 13 }}>{t.noData}</div>
              )}
              {!loading[activeModal] && filtered.map((entry, idx) => renderRow(entry, idx))}
            </div>

            {/* Footer — 数据来源 (real provenance) + subject-req legend */}
            <div data-testid="asm-source-footer" style={{ padding: '12px 20px', borderTop: '1px solid var(--pb-border)', background: 'var(--pb-surface-alt)', fontSize: 11, color: 'var(--pb-fg-muted)', lineHeight: 1.6, flexShrink: 0 }}>
              {currentMeta && currentMeta.source ? (
                <React.Fragment>
                  <div>
                    {t.sourceLabel}：
                    <a href={currentMeta.source.url} target="_blank" rel="noopener noreferrer" style={{ color: cfg.color }}>
                      {currentMeta.source.title}
                    </a>
                    {currentMeta.source.publishedAt && <span>（{currentMeta.source.publisher || ''} {currentMeta.source.publishedAt}）</span>}
                  </div>
                  {currentMeta.subjectReqLegend && <div style={{ marginTop: 4 }}>{currentMeta.subjectReqLegend}</div>}
                </React.Fragment>
              ) : (
                <div>{zh ? '数据来源：海南省考试局公开公告。' : 'Source: Hainan Provincial Examination Bureau public announcements.'}</div>
              )}
            </div>
          </div>
        </div>
      , document.body)}
    </React.Fragment>
  );
};

window.ArtSportsMilitaryBlock = ArtSportsMilitaryBlock;
