/* MycoPolicy — extras: TileMap, CompareMode, CorrectionsModal
   ───────────────────────────────────────────────────────────────── */

const STATUS3 = window.MP_STATUS_DEFS;
const { useState: useS, useMemo: useM, useEffect: useE, useRef: useR } = React;

// ─── TILE MAP ──────────────────────────────────────────────────────────
// Daily Kos / NPR-style square-grid US map. Civic, scannable, no
// distorted Mercator. Each state is a clickable square colored by status.
const TILE_POSITIONS = {
  ME: [10, 0],
  AK: [0, 1],  VT: [9, 1], NH: [10, 1],
  WA: [1, 2], ID: [2, 2], MT: [3, 2], ND: [4, 2], MN: [5, 2], WI: [6, 2], MI: [8, 2], NY: [9, 2], MA: [10, 2],
  OR: [1, 3], NV: [2, 3], WY: [3, 3], SD: [4, 3], IA: [5, 3], IL: [6, 3], IN: [7, 3], OH: [8, 3], PA: [9, 3], NJ: [10, 3], CT: [11, 3], RI: [12, 3],
  CA: [1, 4], UT: [2, 4], CO: [3, 4], NE: [4, 4], MO: [5, 4], KY: [6, 4], WV: [7, 4], VA: [8, 4], MD: [9, 4], DE: [10, 4],
  AZ: [2, 5], NM: [3, 5], KS: [4, 5], AR: [5, 5], TN: [6, 5], NC: [7, 5], SC: [8, 5], DC: [9, 5],
  HI: [0, 6],            OK: [4, 6], LA: [5, 6], MS: [6, 6], AL: [7, 6], GA: [8, 6],
                         TX: [4, 7],                                     FL: [9, 7]
};

function TileMap({ states, statusFilter, roleFilter, onPick, compareMode, compareList, toggleCompare }) {
  const [hover, setHover] = useS(null);
  const byPostal = useM(() => {
    const m = {};
    states.forEach(s => { m[s.postal] = s; });
    return m;
  }, [states]);

  // Status color map (CSS vars from stylesheet)
  const statusFill = {
    active_licensing:           'var(--st-active)',
    enacted_not_open:           'var(--st-enacted)',
    limited_pilot_or_research:  'var(--st-pilot)',
    trigger_law:                'var(--st-trigger)',
    local_deprioritization_only:'var(--st-local)',
    watchlist:                  'var(--st-watch)',
    prohibited_no_pathway:      'var(--st-none)'
  };

  const COLS = 13, ROWS = 8;
  const TW = 56; // tile width
  const GAP = 4;
  const W = COLS * (TW + GAP);
  const H = ROWS * (TW + GAP);

  const matches = (s) => {
    if (statusFilter !== 'all' && s.status !== statusFilter) return false;
    if (roleFilter && !s.applicable_roles.includes(roleFilter)) return false;
    return true;
  };

  return (
    <div className="tile-map-wrap">
      <div className="tile-map" style={{ width: W, height: H, position: 'relative', margin: '0 auto' }}>
        {Object.entries(TILE_POSITIONS).map(([postal, [col, row]]) => {
          const state = byPostal[postal];
          if (!state) return null;
          const isMatch = matches(state);
          const isCompared = compareList?.includes(postal);
          const isHovered = hover === postal;
          return (
            <div
              key={postal}
              className={`tile ${isMatch ? 'is-match' : 'is-dim'} ${isCompared ? 'is-compared' : ''} ${isHovered ? 'is-hover' : ''}`}
              style={{
                position: 'absolute',
                left: col * (TW + GAP),
                top: row * (TW + GAP),
                width: TW, height: TW,
                background: isMatch ? statusFill[state.status] : 'transparent',
                borderColor: isMatch ? statusFill[state.status] : 'var(--rule)',
              }}
              onClick={() => compareMode ? toggleCompare(postal) : onPick(state)}
              onMouseEnter={() => setHover(postal)}
              onMouseLeave={() => setHover(null)}
            >
              <div className="tile-postal">{postal}</div>
              {state.commercial_license_available && <div className="tile-dot" />}
              {isCompared && <div className="tile-check">✓</div>}
            </div>
          );
        })}

        {/* Hover tooltip */}
        {hover && byPostal[hover] && (() => {
          const s = byPostal[hover];
          const [col, row] = TILE_POSITIONS[hover];
          const px = col * (TW + GAP) + TW / 2;
          const py = row * (TW + GAP);
          const right = col > COLS - 4;
          const bottom = row > ROWS - 3;
          return (
            <div className="tile-tip" style={{
              left: right ? px - 220 : px - 20,
              top: bottom ? py - 110 : py + TW + 8,
            }}>
              <div className="tile-tip-name">{s.state} <span className="tile-tip-postal">{s.postal}</span></div>
              <window.StatusBadge status={s.status} />
              <div className="tile-tip-summary">{s.summary.slice(0, 130)}{s.summary.length > 130 ? '…' : ''}</div>
              <div className="tile-tip-hint">
                {compareMode ? 'Click to add/remove from compare' : 'Click to open state page'}
              </div>
            </div>
          );
        })()}
      </div>

      {/* Map legend */}
      <div className="tile-legend">
        {[
          'active_licensing',
          'enacted_not_open',
          'limited_pilot_or_research',
          'trigger_law',
          'local_deprioritization_only',
          'watchlist',
          'prohibited_no_pathway'
        ].map(k => (
          <span key={k} className="tile-legend-item">
            <span className="tile-legend-swatch" style={{ background: statusFill[k] }} />
            {STATUS3[k].label}
          </span>
        ))}
        <span className="tile-legend-item" style={{ marginLeft: 'auto' }}>
          <span className="tile-legend-dot" /> = applications open
        </span>
      </div>
    </div>
  );
}

// ─── COMPARE BAR + TABLE ─────────────────────────────────────────────
function CompareBar({ compareMode, setCompareMode, compareList, setCompareList, states, onShow }) {
  const stateMap = useM(() => {
    const m = {};
    states.forEach(s => { m[s.postal] = s; });
    return m;
  }, [states]);

  return (
    <div className={`compare-bar ${compareMode ? 'is-on' : ''}`}>
      <button
        className={`compare-toggle ${compareMode ? 'active' : ''}`}
        onClick={() => { setCompareMode(!compareMode); if (compareMode) setCompareList([]); }}
      >
        <window.Ico.check /> {compareMode ? 'Comparing…' : 'Compare states'}
      </button>
      {compareMode && (
        <>
          <span className="compare-hint">
            {compareList.length === 0
              ? 'Click states on the map or in the index to add up to 4'
              : `${compareList.length}/4 selected`}
          </span>
          <div className="compare-chips">
            {compareList.map(p => (
              <span key={p} className="compare-chip">
                {stateMap[p]?.state || p}
                <button onClick={() => setCompareList(compareList.filter(x => x !== p))}>×</button>
              </span>
            ))}
          </div>
          {compareList.length >= 2 && (
            <button className="compare-show" onClick={onShow}>
              Show comparison →
            </button>
          )}
          {compareList.length > 0 && (
            <button className="compare-clear" onClick={() => setCompareList([])}>Clear</button>
          )}
        </>
      )}
    </div>
  );
}

function CompareModal({ open, onClose, states, postals }) {
  useE(() => {
    if (!open) return;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = ''; document.removeEventListener('keydown', onKey); };
  }, [open, onClose]);

  if (!open) return null;
  const picked = postals.map(p => states.find(s => s.postal === p)).filter(Boolean);

  const rows = [
    { label: 'Status', render: s => <window.StatusBadge status={s.status} /> },
    { label: 'Postal', render: s => <span className="cmp-mono">{s.postal}</span> },
    { label: 'Apply now?', render: s => s.commercial_license_available
        ? <span className="cmp-yes">✓ Yes</span>
        : <span className="cmp-no">No</span>
    },
    { label: 'Regulator', render: s => <span className="cmp-small">{s.enrich?.regulator || '—'}</span> },
    { label: 'License paths', render: s => s.license_paths.length === 0
        ? <span className="cmp-muted">None</span>
        : <ul className="cmp-list">{s.license_paths.slice(0, 5).map((p, i) => <li key={i}>{p}</li>)}{s.license_paths.length > 5 && <li>+{s.license_paths.length - 5} more</li>}</ul>
    },
    { label: 'Cultivator', render: s => qaCell(s, 'cultivator') },
    { label: 'Manufacturer', render: s => qaCell(s, 'manufacturer') },
    { label: 'Service center', render: s => qaCell(s, 'service_center') },
    { label: 'Clinician / Facilitator', render: s => qaCell(s, 'clinician') },
    { label: 'Testing lab', render: s => qaCell(s, 'lab') },
    { label: 'Research / Hospital', render: s => qaCell(s, 'research') },
    { label: 'What to watch', render: s => s.enrich?.watch?.length > 0
        ? <ul className="cmp-list">{s.enrich.watch.slice(0, 3).map((w, i) => <li key={i}>{w}</li>)}</ul>
        : <span className="cmp-muted">—</span>
    },
    { label: 'Last verified', render: s => <span className="cmp-mono">{s.enrich?.last_verified || '2026-05-23'}</span> },
    { label: 'Sources', render: s => s.enrich?.sources?.length > 0
        ? <span className="cmp-mono">{s.enrich.sources.length} sources</span>
        : <span className="cmp-muted">—</span>
    }
  ];

  return (
    <div className="cmp-scrim" onClick={onClose}>
      <div className="cmp-modal" onClick={e => e.stopPropagation()}>
        <div className="cmp-head">
          <div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)' }}>Side-by-side comparison</div>
            <h2 style={{ fontFamily: 'var(--font-serif)', fontSize: 24, marginTop: 4, letterSpacing: '-0.015em' }}>
              {picked.map(s => s.state).join(' vs. ')}
            </h2>
          </div>
          <button className="cmp-close" onClick={onClose}>×</button>
        </div>
        <div className="cmp-body">
          <table className="cmp-table">
            <thead>
              <tr>
                <th />
                {picked.map(s => (
                  <th key={s.postal}>
                    <div style={{ fontFamily: 'var(--font-serif)', fontSize: 18, fontWeight: 600, marginBottom: 4 }}>{s.state}</div>
                    <window.StatusBadge status={s.status} />
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {rows.map((r, i) => (
                <tr key={i}>
                  <th>{r.label}</th>
                  {picked.map(s => <td key={s.postal}>{r.render(s)}</td>)}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}
function qaCell(s, key) {
  const ans = s.enrich?.can_apply?.[key]
    || (s.commercial_license_available && s.applicable_roles?.includes(key) ? 'yes' : 'no');
  if (ans === 'yes') return <span className="cmp-yes">✓ Yes</span>;
  if (ans === 'watch') return <span className="cmp-watch">◐ Watch</span>;
  return <span className="cmp-no">– No</span>;
}

// ─── CORRECTIONS MODAL ───────────────────────────────────────────────
function CorrectionsModal({ open, onClose, states, prefillState }) {
  const [form, setForm] = useS({ state: '', email: '', source: '', notes: '', kind: 'outdated' });
  const [sent, setSent] = useS(false);
  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));

  useE(() => {
    if (open && prefillState) setForm(f => ({ ...f, state: prefillState }));
    if (open) {
      document.body.style.overflow = 'hidden';
      const onKey = (e) => { if (e.key === 'Escape') onClose(); };
      document.addEventListener('keydown', onKey);
      return () => { document.body.style.overflow = ''; document.removeEventListener('keydown', onKey); };
    }
  }, [open, prefillState, onClose]);

  if (!open) return null;
  const submit = (e) => {
    e.preventDefault();
    setSent(true);
    setTimeout(() => { setSent(false); onClose(); setForm({ state: '', email: '', source: '', notes: '', kind: 'outdated' }); }, 2200);
  };

  return (
    <div className="cor-scrim" onClick={onClose}>
      <div className="cor-modal" onClick={e => e.stopPropagation()}>
        <div className="cor-head">
          <div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--muted)' }}>Submit a correction</div>
            <h2 style={{ fontFamily: 'var(--font-serif)', fontSize: 24, marginTop: 4, letterSpacing: '-0.015em' }}>Help us keep this <em style={{ color: 'var(--green)', fontStyle: 'italic', fontWeight: 500 }}>accurate</em></h2>
          </div>
          <button className="cor-close" onClick={onClose}>×</button>
        </div>
        <div className="cor-body">
          {sent ? (
            <div className="cor-success">
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--green)', marginBottom: 6 }}>Received ✓</div>
              <div style={{ fontSize: 15 }}>Thanks. We'll review your correction and update the page if confirmed. <em>(Prototype — nothing was actually sent.)</em></div>
            </div>
          ) : (
            <form onSubmit={submit} className="cor-form">
              <p className="cor-lead">Spotted something outdated, incomplete, or wrong? Tell us — please include an official source link so we can verify quickly.</p>

              <div className="cor-row">
                <label>State or jurisdiction *</label>
                <select required value={form.state} onChange={e => update('state', e.target.value)}>
                  <option value="">Select…</option>
                  {Object.keys(window.MP_POSTAL).sort().map(name => (
                    <option key={name} value={name}>{name}</option>
                  ))}
                </select>
              </div>

              <div className="cor-row">
                <label>Type of correction *</label>
                <div className="cor-seg">
                  {[
                    { v: 'outdated', l: 'Outdated' },
                    { v: 'incorrect', l: 'Incorrect' },
                    { v: 'missing', l: 'Missing info' },
                    { v: 'broken', l: 'Broken link' },
                    { v: 'other', l: 'Other' }
                  ].map(o => (
                    <button key={o.v} type="button"
                            className={form.kind === o.v ? 'active' : ''}
                            onClick={() => update('kind', o.v)}>{o.l}</button>
                  ))}
                </div>
              </div>

              <div className="cor-row">
                <label>What should we update? *</label>
                <textarea required rows={4} value={form.notes} onChange={e => update('notes', e.target.value)} placeholder="Be as specific as you can. E.g. “The NM producer permit rules were updated on May 18, the FAQ link now points to a 404.”" />
              </div>

              <div className="cor-row">
                <label>Official source URL</label>
                <input type="url" value={form.source} onChange={e => update('source', e.target.value)} placeholder="https://www.nmhealth.org/…" />
                <div className="cor-fine">Agency, statute, bill, or rulemaking page preferred. Press coverage accepted only when primary sources are not yet available.</div>
              </div>

              <div className="cor-row">
                <label>Your email (optional)</label>
                <input type="email" value={form.email} onChange={e => update('email', e.target.value)} placeholder="you@firm.com" />
                <div className="cor-fine">We will only contact you if we have a clarifying question.</div>
              </div>

              <div className="cor-actions">
                <button type="button" className="cor-cancel" onClick={onClose}>Cancel</button>
                <button type="submit" className="cor-submit">Submit correction</button>
              </div>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TileMap, CompareBar, CompareModal, CorrectionsModal });
