/* =============================================================
   Skjult spill — kast lagringsmedier i bøttene.
   Verdien ligger i mediet, bøtta ganger opp.
   ============================================================= */

const KASTBARE = [
  { id:"diskett", navn:"Diskett",   poeng:10, riktig:"rest", tyngde:0.34, spinn:0.05, margin:  3 },
  { id:"cd",      navn:"CD-ROM",    poeng:30, riktig:"rest", tyngde:0.26, spinn:0.26, margin: -3 },
  { id:"usb",     navn:"Minnepenn", poeng:50, riktig:"ee",   tyngde:0.30, spinn:0.14, margin:-10 },
];

/* Plastdunken står nærmest og er bredest — den er også alltid feil.
   Hardplast som ikke er emballasje skal i restavfall. */
const BOTTER = [
  { id:"plast", merke:"PLAST",      bredde:104 },
  { id:"rest",  merke:"RESTAVFALL", bredde:80  },
  { id:"ee",    merke:"EE-AVFALL",  bredde:60  },
];

const BOTTENAVN = { plast:"plastemballasje", rest:"restavfall", ee:"EE-avfall" };

const SPILLTID = 20;
const KAST_K = 0.063;
const KAST_TAK = 22;

function Spill({ lukk }) {
  const lerretRef = useRef(null);
  const valgtRef = useRef(KASTBARE[0]);
  const [valgt, setValgt] = useState(KASTBARE[0]);
  const [poeng, setPoeng] = useState(0);
  const [tid, setTid] = useState(SPILLTID);
  const [ferdig, setFerdig] = useState(false);
  const [best, setBest] = useState(0);
  const [treff, setTreff] = useState(null);
  const [plakat, setPlakat] = useState(false);

  useEffect(() => {
    if (!treff) return;
    const t = setTimeout(() => setTreff(null), treff.riktig ? 2250 : 3250);
    return () => clearTimeout(t);
  }, [treff]);
  const ferdigRef = useRef(false);
  const tidRef = useRef(SPILLTID);

  useEffect(() => { valgtRef.current = valgt; }, [valgt]);
  useEffect(() => { ferdigRef.current = ferdig; }, [ferdig]);
  useEffect(() => { tidRef.current = tid; }, [tid]);

  useEffect(() => {
    try { setBest(parseInt(localStorage.getItem("sl-spill-best") || "0", 10)); } catch {}
  }, []);

  useEffect(() => {
    const tast = (e) => {
      if (e.key === "Escape") { lukk(); return; }
      const i = ["1","2","3"].indexOf(e.key);
      if (i >= 0) setValgt(KASTBARE[i]);
    };
    document.addEventListener("keydown", tast);
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", tast); document.body.style.overflow = ""; };
  }, [lukk]);

  useEffect(() => {
    if (ferdig) return;
    const t = setInterval(() => setTid(v => { if (v <= 1) { setFerdig(true); return 0; } return v - 1; }), 1000);
    return () => clearInterval(t);
  }, [ferdig]);

  useEffect(() => {
    if (!ferdig) return;
    setBest(b => {
      if (poeng > b) { try { localStorage.setItem("sl-spill-best", String(poeng)); } catch {} return poeng; }
      return b;
    });
  }, [ferdig, poeng]);

  /* ---------- Motor ---------- */
  useEffect(() => {
    const lerret = lerretRef.current;
    if (!lerret) return;
    const ctx = lerret.getContext("2d");
    let stopp = false;

    const S = { b:0, h:0, dpr:1, ting:null, sikter:false, start:null, naa:null, botter:[], partikler:[], neste:0 };

    const nyTing = () => {
      const m = valgtRef.current;
      S.ting = { ...m, x: S.b * 0.15, y: S.h - 96, vx:0, vy:0, rot:0, vrot:0, kastet:false, dod:false };
    };

    const settOpp = () => {
      /* offsetWidth ignorerer transform — panelet animerer inn fra scale(0.94) */
      S.dpr = Math.min(window.devicePixelRatio || 1, 2);
      S.b = lerret.offsetWidth; S.h = lerret.offsetHeight;
      lerret.width = S.b * S.dpr; lerret.height = S.h * S.dpr;
      ctx.setTransform(S.dpr, 0, 0, S.dpr, 0, 0);
      const gulv = S.h - 80;
      S.botter = BOTTER.map((b, i) => {
        const felt = [{ fra:0.30, til:0.30 }, { fra:0.52, til:0.62 }, { fra:0.78, til:0.90 }][i];
        return { ...b, y: gulv, h: 56, retning: 1,
                 x: S.b * felt.fra,
                 min: S.b * felt.fra, maks: S.b * felt.til,
                 grunnfart: b.id === "ee" ? 0.85 : b.id === "rest" ? 0.45 : 0 };
      });
      if (!S.ting || !S.ting.kastet) nyTing();
    };
    settOpp();
    const etterAnim = setTimeout(settOpp, 480);
    window.addEventListener("resize", settOpp);

    /* --- Tegning av mediene --- */
    const tegnTing = (t) => {
      ctx.save();
      ctx.translate(t.x, t.y);
      ctx.rotate(t.rot);
      ctx.lineWidth = 1.3;

      if (t.id === "diskett") {
        ctx.fillStyle = "#3F4A50"; ctx.strokeStyle = "#2B3338";
        ctx.beginPath(); ctx.roundRect(-19, -19, 38, 38, 3); ctx.fill(); ctx.stroke();
        ctx.fillStyle = "#C9CFD2";                       // metallukker
        ctx.beginPath(); ctx.roundRect(-9, -19, 18, 15, 1.5); ctx.fill();
        ctx.fillStyle = "#2B3338";
        ctx.fillRect(1, -18, 5, 13);
        ctx.fillStyle = "#E8E3D8";                       // etikett
        ctx.beginPath(); ctx.roundRect(-13, 1, 26, 16, 1.5); ctx.fill();
        ctx.fillStyle = "#8E9599";
        ctx.fillRect(-10, 5, 18, 1.6); ctx.fillRect(-10, 9, 13, 1.6);
      }

      else if (t.id === "cd") {
        const g = ctx.createLinearGradient(-15, -15, 15, 15);
        g.addColorStop(0, "#D8DEE0"); g.addColorStop(0.4, "#EFEAE0");
        g.addColorStop(0.6, "#C3CDD2"); g.addColorStop(1, "#E4DCCF");
        ctx.fillStyle = g; ctx.strokeStyle = "rgba(74,90,98,0.55)";
        ctx.beginPath(); ctx.arc(0, 0, 15, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
        ctx.strokeStyle = "rgba(74,90,98,0.25)";
        ctx.beginPath(); ctx.arc(0, 0, 10, 0, Math.PI * 2); ctx.stroke();
        ctx.fillStyle = "#F4F1EA"; ctx.strokeStyle = "rgba(74,90,98,0.5)";
        ctx.beginPath(); ctx.arc(0, 0, 4.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
      }

      else {                                             // minnepenn
        ctx.fillStyle = "#4A5A62"; ctx.strokeStyle = "#333F45";
        ctx.beginPath(); ctx.roundRect(-6, -11, 12, 20, 2.5); ctx.fill(); ctx.stroke();
        ctx.fillStyle = "#B9C1C5";                       // kontakt
        ctx.beginPath(); ctx.roundRect(-4.5, -17, 9, 7, 1); ctx.fill(); ctx.stroke();
        ctx.fillStyle = "#A9683F";                       // lampe
        ctx.beginPath(); ctx.arc(0, 5, 1.8, 0, Math.PI * 2); ctx.fill();
      }
      ctx.restore();
    };

    const tegnBotte = (b) => {
      ctx.save();
      ctx.strokeStyle = "rgba(74,90,98,0.55)"; ctx.lineWidth = 1.5;
      ctx.fillStyle = "rgba(244,241,234,0.5)";
      ctx.beginPath();
      ctx.moveTo(b.x - b.bredde/2, b.y);
      ctx.lineTo(b.x - b.bredde/2 + 7, b.y + b.h);
      ctx.lineTo(b.x + b.bredde/2 - 7, b.y + b.h);
      ctx.lineTo(b.x + b.bredde/2, b.y);
      ctx.closePath(); ctx.fill(); ctx.stroke();
      ctx.fillStyle = "#4A5A62"; ctx.textAlign = "center";
      ctx.font = "600 9.5px ui-monospace, monospace";
      ctx.fillText(b.merke, b.x, b.y + b.h - 20);
      ctx.restore();
    };

    const sikteLinje = () => {
      if (!S.sikter || !S.start || !S.naa || !S.ting) return;
      const t = S.ting;
      let dx = Math.max(-KAST_TAK, Math.min(KAST_TAK, (S.start.x - S.naa.x) * KAST_K));
      let dy = Math.max(-KAST_TAK, Math.min(KAST_TAK, (S.start.y - S.naa.y) * KAST_K));
      ctx.save(); ctx.fillStyle = "rgba(74,90,98,0.4)";
      let x = t.x, y = t.y;
      for (let i = 0; i < 46; i++) {
        x += dx; y += dy; dy += t.tyngde;
        if (y > S.h) break;
        if (i % 2 === 0) { ctx.beginPath(); ctx.arc(x, y, 2.2 - i * 0.03, 0, Math.PI * 2); ctx.fill(); }
      }
      ctx.restore();
    };

    const sloyfe = () => {
      if (stopp) return;
      ctx.clearRect(0, 0, S.b, S.h);

      /* Jo mindre tid igjen, jo raskere flytter dunkene seg — fra 1× til 2,6×.
         Plastdunken står i ro uansett. */
      const stress = 1 + (1 - Math.max(0, tidRef.current) / SPILLTID) * 1.6;
      S.botter.forEach(b => {
        if (!b.grunnfart) return;
        b.fart = b.grunnfart * stress;
        b.x += b.fart * b.retning;
        if (b.x > b.maks) { b.x = b.maks; b.retning = -1; }
        if (b.x < b.min)  { b.x = b.min;  b.retning = 1; }
      });

      ctx.strokeStyle = "rgba(74,90,98,0.22)"; ctx.lineWidth = 1;
      ctx.beginPath(); ctx.moveTo(0, S.h - 24); ctx.lineTo(S.b, S.h - 24); ctx.stroke();

      S.botter.forEach(tegnBotte);
      sikteLinje();

      const t = S.ting;
      if (t && !t.dod) {
        if (t.kastet) {
          t.x += t.vx; t.y += t.vy; t.vy += t.tyngde; t.rot += t.vrot;
          S.botter.forEach(b => {
            if (t.vy > 0 && t.y > b.y - 6 && t.y < b.y + 24 &&
                Math.abs(t.x - b.x) < b.bredde/2 - 8 + t.margin) {
              t.dod = true;
              const riktig = b.id === t.riktig;
              const sum = riktig ? t.poeng : -5;
              if (!ferdigRef.current) {
                setPoeng(p => Math.max(0, p + sum));
                setTreff({
                  id: Date.now(), riktig,
                  tekst: riktig ? "+" + t.poeng + " riktig sortert"
                                : "Feilsortert −5 · " + t.navn + " skal i " + BOTTENAVN[t.riktig],
                });
              }
              const farge = riktig ? "74,90,98" : "169,104,63";
              for (let i = 0; i < (riktig ? 18 : 8); i++)
                S.partikler.push({ x:t.x, y:t.y, farge, vx:(Math.random()-0.5)*4.5, vy:-Math.random()*4.5, liv:1 });
              S.neste = performance.now() + 300;
            }
          });
          if (!t.dod && (t.y > S.h - 24 || t.x > S.b + 40 || t.x < -40)) {
            t.dod = true; S.neste = performance.now() + 240;
          }
        }
        tegnTing(t);
      }
      if (t && t.dod && S.neste && performance.now() > S.neste) { S.neste = 0; nyTing(); }

      S.partikler = S.partikler.filter(p => p.liv > 0);
      S.partikler.forEach(p => {
        p.x += p.vx; p.y += p.vy; p.vy += 0.22; p.liv -= 0.028;
        ctx.fillStyle = "rgba(" + (p.farge || "74,90,98") + "," + Math.max(0, p.liv) + ")";
        ctx.beginPath(); ctx.arc(p.x, p.y, 2.6, 0, Math.PI * 2); ctx.fill();
      });

      requestAnimationFrame(sloyfe);
    };
    sloyfe();

    /* --- Kasting: flytt og slipp lyttes på window, ellers stopper
           draget så snart pekeren forlater lerretet --- */
    const punkt = (e) => {
      const r = lerret.getBoundingClientRect();
      const k = e.touches && e.touches[0] ? e.touches[0] : (e.changedTouches ? e.changedTouches[0] : e);
      return { x: k.clientX - r.left, y: k.clientY - r.top };
    };
    const ned = (e) => {
      if (ferdigRef.current || !S.ting || S.ting.kastet) return;
      e.preventDefault(); S.sikter = true; S.start = punkt(e); S.naa = S.start;
    };
    const flytt = (e) => { if (S.sikter) { e.preventDefault(); S.naa = punkt(e); } };
    const opp = (e) => {
      if (!S.sikter || !S.ting) return;
      S.sikter = false;
      const dx = S.start.x - S.naa.x, dy = S.start.y - S.naa.y;
      if (Math.abs(dx) + Math.abs(dy) < 14) return;
      S.ting.vx = Math.max(-KAST_TAK, Math.min(KAST_TAK, dx * KAST_K));
      S.ting.vy = Math.max(-KAST_TAK, Math.min(KAST_TAK, dy * KAST_K));
      S.ting.vrot = S.ting.spinn * (dx > 0 ? 1 : -1) * 1.4;
      S.ting.kastet = true;
    };

    lerret.addEventListener("mousedown", ned);
    window.addEventListener("mousemove", flytt);
    window.addEventListener("mouseup", opp);
    lerret.addEventListener("touchstart", ned, { passive:false });
    window.addEventListener("touchmove", flytt, { passive:false });
    window.addEventListener("touchend", opp);

    S.byttTing = () => { if (S.ting && !S.ting.kastet) nyTing(); };
    lerret.__spill = S;

    return () => {
      stopp = true; clearTimeout(etterAnim);
      window.removeEventListener("resize", settOpp);
      lerret.removeEventListener("mousedown", ned);
      window.removeEventListener("mousemove", flytt);
      window.removeEventListener("mouseup", opp);
      lerret.removeEventListener("touchstart", ned);
      window.removeEventListener("touchmove", flytt);
      window.removeEventListener("touchend", opp);
    };
  }, []);

  /* Bytt medium uten å starte motoren på nytt */
  useEffect(() => {
    const l = lerretRef.current;
    if (l && l.__spill && l.__spill.byttTing) l.__spill.byttTing();
  }, [valgt]);

  const start = () => { setPoeng(0); setTid(SPILLTID); setFerdig(false); setTreff(null); };

  const tilSkjema = () => {
    lukk();
    setTimeout(() => window.dispatchEvent(new CustomEvent("sl:apne-skjema")), 220);
  };

  return (
    <div className="sl-spill" role="dialog" aria-modal="true" aria-label="Skjult spill">
      <div className="sl-spill__bak" onClick={lukk}></div>
      <div className="sl-spill__panel">
        <div className="sl-spill__topp">
          <div>
            <span className="sl-slash">/ skjult nivå</span>
            <h2 className="sl-spill__tittel">Hjelp oss å kildesortere</h2>
          </div>
          <button className="sl-spill__lukk" onClick={lukk} aria-label="Lukk spill">×</button>
        </div>

        <div className="sl-spill__maalere">
          <span><strong>{poeng}</strong> poeng</span>
          <span className={tid <= 7 && !ferdig ? "sl-spill__hast" : undefined}><strong>{tid}</strong> sek</span>
          <span>rekord <strong>{best}</strong></span>
        </div>

        <div className="sl-spill__velger" role="radiogroup" aria-label="Velg hva du vil kaste">
          {KASTBARE.map((k, i) => (
            <button key={k.id} role="radio" aria-checked={valgt.id === k.id}
                    className={"sl-medium" + (valgt.id === k.id ? " sl-medium--valgt" : "")}
                    onClick={() => setValgt(k)}>
              <MediumIkon id={k.id}/>
              <span className="sl-medium__navn">{k.navn}</span>
              <span className="sl-medium__fasit">→ {BOTTENAVN[k.riktig]}</span>
              <span className="sl-medium__poeng">{k.poeng}p</span>
              <span className="sl-medium__tast">{i + 1}</span>
            </button>
          ))}
        </div>

        <div className="sl-spill__flate">
          <canvas ref={lerretRef} className="sl-spill__lerret"></canvas>
          {treff && <span key={treff.id} className={"sl-spill__treff" + (treff.riktig ? "" : " sl-spill__treff--feil")}>{treff.tekst}</span>}
        </div>

          {ferdig && (
          <div className="sl-spill__slutt">
            <p className="sl-spill__scorelabel">Din score ble</p>
            <p className="sl-spill__sluttall">{poeng}</p>
            <p className="sl-spill__slutttekst">{poeng >= best && poeng > 0 ? "Ny rekord." : "Tiden er ute."}</p>

            <div className="sl-spill__pitch">
              <span className="sl-slash">/ ta det med på jobb</span>
              <p>
                Vi har laget en <strong>plakat til kontorveggen</strong> — hva som skal hvor,
                hva som heller bør selges, og de nærmeste innleveringsstedene deres.
              </p>
              <button className="sl-btn sl-btn--primary sl-spill__plakat"
                      onClick={() => setPlakat(true)}>
                Heng opp plakat på kontoret ↓
              </button>
            </div>

            <div className="sl-spill__knapper">
              <button className="sl-btn sl-btn--ghost" onClick={start}>Prøv igjen</button>
              <button className="sl-btn sl-btn--ghost" onClick={tilSkjema}>Har du lyst til å snakke mer om e-læring? →</button>
            </div>
            <button className="sl-spill__lukklenke" onClick={lukk}>Tilbake til jobb</button>

            <Eavfall/>
          </div>
        )}
        {plakat && <PlakatSkjema lukk={() => setPlakat(false)}/>}

        <p className="sl-spill__hjelp">
          Velg avfall, dra fra det og slipp for å kaste. Riktig dunk gir poeng, feil gir trekk.
          Plastdunken står nærmest og er alltid feil — hardplast som ikke er emballasje skal i restavfall.
        </p>

        <div className="sl-spill__fot">
          <span>Vil dere ha reglene på veggen?</span>
          <button className="sl-spill__fotknapp" onClick={() => setPlakat(true)}>
            Last ned plakat ↓
          </button>
        </div>
      </div>
    </div>
  );
}

function MediumIkon({ id }) {
  if (id === "diskett") return (
    <svg viewBox="0 0 24 24" className="sl-medium__ikon" aria-hidden="true">
      <rect x="3" y="3" width="18" height="18" rx="2" fill="currentColor" opacity="0.9"/>
      <rect x="8" y="3" width="8" height="7" rx="1" fill="#E8E3D8"/>
      <rect x="13.5" y="4" width="2" height="5" fill="currentColor"/>
      <rect x="6.5" y="13" width="11" height="8" rx="1" fill="#E8E3D8"/>
    </svg>
  );
  if (id === "cd") return (
    <svg viewBox="0 0 24 24" className="sl-medium__ikon" aria-hidden="true">
      <circle cx="12" cy="12" r="9" fill="currentColor" opacity="0.9"/>
      <circle cx="12" cy="12" r="5.6" fill="none" stroke="#E8E3D8" strokeWidth="1"/>
      <circle cx="12" cy="12" r="2.4" fill="#F4F1EA"/>
    </svg>
  );
  return (
    <svg viewBox="0 0 24 24" className="sl-medium__ikon" aria-hidden="true">
      <rect x="8" y="7" width="8" height="14" rx="2" fill="currentColor" opacity="0.9"/>
      <rect x="9.5" y="3" width="5" height="5" rx="1" fill="#B9C1C5"/>
      <circle cx="12" cy="17" r="1.3" fill="#A9683F"/>
    </svg>
  );
}
