// app-map.jsx — Interactive Europe map for Civify geography lessons
// Country outlines come from app-map-data.js (real Natural Earth geometry).
// Exports: window.EuropeMap, window.MapExercise, window.CIVIFY_MAP_NAMES
(function () {
  const { useState } = React;

  const GEO = window.CIVIFY_MAP_GEO;
  const LANDS = GEO.LANDS;          // interactive countries: { code: { name, d } }
  const BG_LANDS = GEO.BG;          // non-interactive context shapes
  const VIEW = `0 0 ${GEO.W} ${GEO.H}`;

  const NAMES = {};
  Object.keys(LANDS).forEach((k) => (NAMES[k] = LANDS[k].name));

  // ── inject scoped styles once ───────────────────────────────
  if (!document.getElementById('cf-map-styles')) {
    const s = document.createElement('style');
    s.id = 'cf-map-styles';
    s.textContent = `
    .cf-map{border-radius:20px;border:1px solid var(--line);overflow:hidden;
      background:color-mix(in srgb,#6FA8CE 18%, var(--bg));}
    .cf-map svg{display:block;width:100%;height:auto;}
    .cf-map .land{fill:var(--card);stroke:color-mix(in srgb,var(--soft) 45%, transparent);
      stroke-width:0.9;stroke-linejoin:round;stroke-linecap:round;}
    .cf-map .land.bg{fill:color-mix(in srgb,var(--card) 45%, transparent);
      stroke:color-mix(in srgb,var(--soft) 22%, transparent);pointer-events:none;}
    .cf-map .land.pick{cursor:pointer;}
    @media (hover:hover){
      .cf-map .land.pick:hover{fill:color-mix(in srgb,var(--o) 20%, var(--card));}
    }
    .cf-map .land.sel{fill:color-mix(in srgb,var(--o) 55%, var(--card));
      stroke:var(--o);stroke-width:1.6;}
    .cf-map .land.hl{fill:color-mix(in srgb,var(--o) 55%, var(--card));
      stroke:var(--o);stroke-width:1.6;animation:cfMapHl 1.6s ease-in-out infinite;}
    @media (prefers-reduced-motion: reduce){ .cf-map .land.hl{animation:none;} }
    @keyframes cfMapHl{0%,100%{opacity:1;}50%{opacity:.55;}}
    .cf-map .land.right{fill:#5CBE8E;stroke:#2FA36B;stroke-width:1.6;}
    .cf-map .land.wrong{fill:#EE9090;stroke:#E25555;stroke-width:1.6;}
    .cf-map .land.done-right{fill:#5CBE8E;stroke:#2FA36B;stroke-width:1.2;}
    .cf-map .land.done-miss{fill:color-mix(in srgb,var(--soft) 38%, var(--card));
      stroke:color-mix(in srgb,var(--soft) 70%, transparent);stroke-width:1.2;}
    .cf-map .land.flash-wrong{fill:#EE9090;stroke:#E25555;stroke-width:1.6;animation:cfMapFlash .45s ease;}
    @keyframes cfMapFlash{0%{fill:#E25555;}100%{fill:#EE9090;}}
    .cf-map-cap{display:flex;align-items:center;justify-content:center;min-height:34px;margin-top:12px;}
    .cf-map-chip{display:inline-flex;align-items:center;gap:7px;background:var(--card);
      border:1px solid var(--line);border-radius:999px;padding:7px 14px;
      font-weight:800;font-size:13.5px;color:var(--ink);}
    .cf-map-chip .swatch{width:9px;height:9px;border-radius:99px;background:var(--o);flex-shrink:0;}
    .cf-map-chip.ok .swatch{background:#2FA36B;}
    .cf-map-chip.no .swatch{background:#E25555;}
    .cf-map-hint{font-size:12.5px;font-weight:600;color:var(--soft);}

    /* ── Seterra-style geography game ── */
    .cf-game{position:absolute;inset:0;background:var(--bg);display:flex;flex-direction:column;z-index:45;}
    .cf-gtop{padding:58px 18px 10px;display:flex;align-items:center;gap:12px;flex-shrink:0;}
    .cf-gtop .cf-x{width:34px;height:34px;border-radius:99px;border:none;background:#f0e7dd;color:var(--soft);
      display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;}
    .cf-gprog{flex:1;height:11px;border-radius:99px;background:#efe6dc;overflow:hidden;}
    .cf-gprog > i{display:block;height:100%;background:linear-gradient(90deg,#46B377,#1F8A5B);border-radius:99px;
      transition:width .35s cubic-bezier(.4,0,.2,1);}
    .cf-gscore{display:inline-flex;align-items:center;gap:6px;background:var(--card);border:1px solid var(--line);
      border-radius:999px;padding:6px 12px;font-weight:800;font-size:13.5px;color:#1F8A5B;flex-shrink:0;}
    .cf-gbody{flex:1;display:flex;flex-direction:column;padding:8px 18px 14px;min-height:0;}
    .cf-gask{flex-shrink:0;padding:6px 2px 14px;}
    .cf-gask .cf-kick{color:#1F8A5B;}
    .cf-gask .name{font-family:'Sora',sans-serif;font-size:27px;font-weight:800;letter-spacing:-.02em;line-height:1.1;}
    .cf-gmapwrap{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;}
    .cf-gmapwrap .cf-map{width:auto;height:100%;max-width:100%;display:flex;align-items:center;justify-content:center;
      background:none;border:none;overflow:visible;}
    .cf-gmapwrap .cf-map svg{width:auto;height:100%;max-width:100%;max-height:100%;}
    .cf-gfeed{flex-shrink:0;min-height:30px;display:flex;align-items:center;justify-content:center;
      margin-top:10px;font-weight:700;font-size:14px;text-align:center;}
    .cf-gfeed.ok{color:#1E7D4E;} .cf-gfeed.no{color:#C0392B;}
    /* result */
    .cf-gresult{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;
      justify-content:center;text-align:center;padding:32px;color:#fff;
      background:linear-gradient(160deg,#3FAE73,#1F8A5B 70%);}
    .cf-gresult .tw{width:96px;height:96px;border-radius:30px;background:rgba(255,255,255,.16);
      display:flex;align-items:center;justify-content:center;margin-bottom:22px;animation:cfPop .5s cubic-bezier(.2,1.4,.4,1);}
    @keyframes cfPop{from{transform:scale(.4);opacity:0;}}
    .cf-gresult h2{font-family:'Sora',sans-serif;font-size:30px;font-weight:800;margin:0 0 6px;}
    .cf-gresult .pct{font-family:'Sora',sans-serif;font-size:54px;font-weight:800;margin:6px 0;}
    .cf-gresult p{margin:0 0 26px;opacity:.92;font-weight:500;}
    .cf-gresult .row{display:flex;gap:12px;width:100%;max-width:320px;}
    .cf-gbtn{flex:1;border:none;border-radius:15px;padding:15px;font-family:'Sora',sans-serif;font-weight:700;
      font-size:15px;cursor:pointer;}
    .cf-gbtn.primary{background:#fff;color:#1F8A5B;}
    .cf-gbtn.ghost{background:rgba(255,255,255,.18);color:#fff;}
    `;
    document.head.appendChild(s);
  }

  // ── Map ─────────────────────────────────────────────────────
  // selected: picked country code · highlight: pulsing country (identify mode)
  // checked + target: show right/wrong state · onPick: tap handler
  // statuses: { code: 'correct' | 'missed' } (game mode) · flashWrong: code flashing red
  function EuropeMap({ selected, highlight, target, checked, onPick, statuses, flashWrong }) {
    const interactive = !!onPick && !checked;
    return (
      <div className="cf-map">
        <svg viewBox={VIEW} role="img" aria-label="Karta över Europa">
          {BG_LANDS.map((d, i) => (
            <path key={'bg' + i} className="land bg" d={d}></path>
          ))}
          {Object.keys(LANDS).map((code) => {
            let cls = 'land';
            if (interactive) cls += ' pick';
            if (highlight === code) cls += ' hl';
            if (statuses && statuses[code] === 'correct') cls += ' done-right';
            else if (statuses && statuses[code] === 'missed') cls += ' done-miss';
            if (flashWrong === code) cls += ' flash-wrong';
            if (checked && target) {
              if (code === target) cls += ' right';
              else if (code === selected) cls += ' wrong';
            } else if (selected === code) {
              cls += ' sel';
            }
            return (
              <path
                key={code}
                className={cls}
                d={LANDS[code].d}
                onClick={() => interactive && onPick(code)}
              ></path>
            );
          })}
        </svg>
      </div>
    );
  }

  // ── Map exercise (tap-the-country) ──────────────────────────
  function MapExercise({ step, pick, setPick, checked }) {
    const correct = checked && pick === step.target;
    return (
      <div>
        <EuropeMap
          selected={pick}
          target={checked ? step.target : null}
          checked={checked}
          onPick={(c) => setPick(c)}
        />
        <div className="cf-map-cap">
          {pick ? (
            <span className={'cf-map-chip' + (checked ? (correct ? ' ok' : ' no') : '')}>
              <span className="swatch"></span>
              {checked && !correct ? `${NAMES[pick]} — rätt svar: ${NAMES[step.target]}` : NAMES[pick]}
            </span>
          ) : (
            <span className="cf-map-hint">Tryck på ett land på kartan</span>
          )}
        </div>
      </div>
    );
  }

  window.EuropeMap = EuropeMap;
  window.MapExercise = MapExercise;
  window.CIVIFY_MAP_NAMES = NAMES;

  // ── Seterra-style geography game ────────────────────────────
  const Icon = window.Icon;
  function shuffle(arr) {
    const a = arr.slice();
    for (let i = a.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
  }

  function GeoGame({ onClose, onDone }) {
    const { useState, useRef } = React;
    const codes = Object.keys(LANDS);
    const [order, setOrder] = useState(() => shuffle(codes));
    const [idx, setIdx] = useState(0);
    const [statuses, setStatuses] = useState({});
    const [flash, setFlash] = useState(null);
    const [attempts, setAttempts] = useState(0);
    const [score, setScore] = useState(0);
    const [feedback, setFeedback] = useState(null);
    const [done, setDone] = useState(false);
    const lockRef = useRef(false);
    const flashTimer = useRef(null);

    const total = order.length;
    const target = order[idx];

    const proceed = (nextStatuses) => {
      lockRef.current = true;
      setTimeout(() => {
        lockRef.current = false;
        setFeedback(null);
        setAttempts(0);
        if (idx + 1 >= total) setDone(true);
        else setIdx(idx + 1);
      }, 700);
    };

    const onPick = (code) => {
      if (lockRef.current || done) return;
      if (code === target) {
        const ns = { ...statuses, [target]: 'correct' };
        setStatuses(ns);
        if (attempts === 0) setScore((s) => s + 1);
        setFeedback({ kind: 'ok', text: 'Rätt — ' + NAMES[target] + '!' });
        proceed(ns);
      } else {
        clearTimeout(flashTimer.current);
        setFlash(code);
        flashTimer.current = setTimeout(() => setFlash(null), 450);
        const na = attempts + 1;
        setAttempts(na);
        if (na >= 2) {
          const ns = { ...statuses, [target]: 'missed' };
          setStatuses(ns);
          setFeedback({ kind: 'no', text: 'Det var ' + NAMES[code] + '. ' + NAMES[target] + ' var här.' });
          proceed(ns);
        } else {
          setFeedback({ kind: 'no', text: 'Det där är ' + NAMES[code] + '. Försök igen!' });
        }
      }
    };

    const restart = () => {
      setOrder(shuffle(codes)); setIdx(0); setStatuses({}); setFlash(null);
      setAttempts(0); setScore(0); setFeedback(null); setDone(false); lockRef.current = false;
    };

    if (done) {
      const pct = Math.round((score / total) * 100);
      const msg = pct >= 90 ? 'Kartmästare!' : pct >= 60 ? 'Snyggt jobbat!' : 'Bra start — kör igen!';
      return (
        <div className="cf-game">
          <div className="cf-gresult">
            <div className="tw"><Icon name="globe" size={48} color="#fff" /></div>
            <h2>{msg}</h2>
            <div className="pct">{pct}%</div>
            <p>{score} av {total} länder rätt på första försöket</p>
            <div className="row">
              <button className="cf-gbtn ghost" onClick={onDone}>Klar</button>
              <button className="cf-gbtn primary" onClick={restart}>Spela igen</button>
            </div>
          </div>
        </div>
      );
    }

    const progress = (idx / total) * 100;
    return (
      <div className="cf-game">
        <div className="cf-gtop">
          <button className="cf-x" onClick={onClose}><Icon name="close" size={18} color="#8C7C6D" /></button>
          <div className="cf-gprog"><i style={{ width: progress + '%' }} /></div>
          <span className="cf-gscore"><Icon name="check" size={15} color="#1F8A5B" /> {score}/{total}</span>
        </div>
        <div className="cf-gbody">
          <div className="cf-gask">
            <div className="cf-kick">Hitta landet · {idx + 1}/{total}</div>
            <div className="name">{NAMES[target]}</div>
          </div>
          <div className="cf-gmapwrap">
            <EuropeMap statuses={statuses} flashWrong={flash} onPick={onPick} />
          </div>
          <div className={'cf-gfeed' + (feedback ? ' ' + feedback.kind : '')}>
            {feedback ? feedback.text : 'Tryck på landet på kartan'}
          </div>
        </div>
      </div>
    );
  }

  window.GeoGame = GeoGame;
})();
