/* ENKII — Case Studies carousel + project showcase. window.ENKIICarousel */
/* global React */
const { useState: useStateK, useEffect: useEffectK, useRef: useRefK } = React;
const KP = window.ENKII_PROJECTS;

/* Error boundary so a refused/misbehaving embed can never crash the app */
class FrameBoundary extends React.Component {
  constructor(p) { super(p); this.state = { dead: false }; }
  static getDerivedStateFromError() { return { dead: true }; }
  componentDidCatch() {}
  render() { return this.state.dead ? (this.props.fallback || null) : this.props.children; }
}

/* Web iframe rendered at a FIXED desktop width (so the site always shows its
   desktop layout) then scaled down to fit the frame — same look at any size. */
const LOGICAL_W = 1280;
function WebIframe({ p, interactive }) {
  const ref = useRefK(null);
  useEffectK(() => {
    const ifr = ref.current;
    if (!ifr) return;
    const view = ifr.parentElement;
    if (!view) return;
    let tries = 0, raf = 0;
    const fit = () => {
      const w = view.clientWidth, h = view.clientHeight;
      if (!w || !h) { if (tries++ < 90) raf = requestAnimationFrame(fit); return; }
      tries = 0;
      const s = w / LOGICAL_W;
      ifr.style.width = LOGICAL_W + "px";
      ifr.style.height = Math.ceil(h / s) + "px";
      ifr.style.transform = "scale(" + s + ")";
    };
    raf = requestAnimationFrame(fit);
    let ro;
    if (window.ResizeObserver) { ro = new ResizeObserver(fit); ro.observe(view); }
    else window.addEventListener("resize", fit);
    return () => { cancelAnimationFrame(raf); if (ro) ro.disconnect(); else window.removeEventListener("resize", fit); };
  }, []);
  return (
    <FrameBoundary>
      <iframe ref={ref} className="frame-iframe frame-iframe-web" src={p.web} title={p.name}
        loading="lazy" referrerPolicy="no-referrer" sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
        style={{ pointerEvents: interactive ? "auto" : "none", transformOrigin: "0 0" }} />
    </FrameBoundary>
  );
}

/* platform badge */
function Plat({ label }) {
  const ic = {
    "iOS": "M12 2.5c.9 0 2 .6 2.6 1.5M8.5 7c-2 0-3.5 1.7-3.5 4.4 0 3 2 6.6 3.7 6.6 1 0 1.4-.6 2.8-.6s1.7.6 2.8.6c1.8 0 3.7-3.7 3.7-6.7 0-2.6-1.6-4.3-3.6-4.3-1.2 0-2 .6-2.9.6-.9 0-1.7-.6-2.8-.6z",
    "Android": "M5 9l-1-2M19 9l1-2M7 9h10v6a2 2 0 01-2 2H9a2 2 0 01-2-2zM9 17v3M15 17v3M8 9a4 4 0 018 0",
    "Web App": "M3 6h18v12H3zM3 10h18M7 14h6",
  }[label] || "M4 6h16v12H4z";
  return (
    <span className="plat">
      <svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d={ic} /></svg>
      {label}
    </span>
  );
}

function StatusBadge({ status, accent, accent2 }) {
  if (status.type === "live") {
    return <span className="st-live"><i />LIVE</span>;
  }
  return (
    <span className="st-bar" title={status.value + "%"}>
      <span className="st-bar-track">
        <span className="st-bar-fill" style={{ width: status.value + "%", background: `linear-gradient(90deg, ${accent}, ${accent2})` }} />
      </span>
      <b style={{ color: accent2 }}>{status.value}%</b>
    </span>
  );
}

function ProjectRow({ p, lang }) {
  return (
    <div className="prow" style={{ "--a": p.accent, "--a2": p.accent2 }}>
      <span className="prow-dot" />
      <span className="prow-name">{p.name}</span>
      <span className="prow-plats">{p.platforms.map((pl) => <Plat key={pl} label={pl} />)}</span>
      <span className="prow-status"><StatusBadge status={p.status} accent={p.accent} accent2={p.accent2} /></span>
    </div>
  );
}

function StatusList({ lang, ui }) {
  return (
    <div className="plist">
      <div className="fs-section-label">{ui.projectsLabel}</div>
      <div className="plist-rows">
        {KP.PROJECTS.map((p) => <ProjectRow key={p.id} p={p} lang={lang} />)}
      </div>
    </div>
  );
}

/* Placeholder shown behind / instead of a live iframe */
function Placeholder({ p, mode, ui, hint, lang }) {
  return (
    <div className="ph-fill" style={{ "--a": p.accent, "--a2": p.accent2 }}>
      <div className="ph-grid" />
      <div className="ph-orb" />
      <div className="ph-body">
        <div className="ph-name">{p.name}</div>
        <div className="ph-sector">{p.sector[lang]}</div>
        {p.tagline && <div className="ph-tag">{p.tagline}</div>}
      </div>
      {hint && <div className="ph-hint">{ui.clickOpen} ↗</div>}
    </div>
  );
}

/* A single device frame (browser or phone) with optional live iframe */
function Frame({ slide, active, interactive, lang, ui, big }) {
  const { p, mode } = slide;
  const isPhone = mode === "phone";
  return (
    <div className={"frame " + (isPhone ? "frame-phone" : "frame-web") + (big ? " frame-big" : "")} style={{ "--a": p.accent, "--a2": p.accent2 }}>
      {isPhone ? (
        <div className="pframe">
          <span className="pframe-notch" />
          <div className="pframe-view">
            <Placeholder p={p} mode={mode} ui={ui} lang={lang} hint={false} />
            {active && <FrameBoundary><iframe key={p.id + "ph"} className="frame-iframe" src={p.web} title={p.name} loading="lazy" referrerPolicy="no-referrer" sandbox="allow-scripts allow-same-origin allow-popups allow-forms" style={{ pointerEvents: interactive ? "auto" : "none" }} /></FrameBoundary>}
          </div>
        </div>
      ) : (
        <div className="bframe">
          <div className="bframe-bar">
            <span className="bf-dots"><i /><i /><i /></span>
            <span className="bframe-url">{p.web.replace("https://", "")}</span>
          </div>
          <div className="bframe-view">
            <Placeholder p={p} mode={mode} ui={ui} lang={lang} hint={false} />
            {active && <WebIframe p={p} interactive={interactive} />}
          </div>
        </div>
      )}
    </div>
  );
}

/* ---------- Compact carousel (inside Case Studies fullscreen) ---------- */
function Carousel({ lang, ui, onOpenBig }) {
  const slides = KP.SLIDES;
  const [i, setI] = useStateK(0);
  const [paused, setPaused] = useStateK(false);
  const n = slides.length;
  useEffectK(() => {
    if (paused) return;
    const t = setInterval(() => setI((v) => (v + 1) % n), 5200);
    return () => clearInterval(t);
  }, [paused, n]);

  const go = (d) => setI((v) => (v + d + n) % n);
  const at = (off) => slides[(i + off + n) % n];

  return (
    <div className="carousel" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      <div className="car-stage">
        <div className="car-slot car-prev"><Frame slide={at(-1)} active={false} interactive={false} lang={lang} ui={ui} /></div>
        <button className="car-center" onClick={() => onOpenBig(i)} aria-label={ui.openSite}>
          <Frame slide={at(0)} active={true} interactive={false} lang={lang} ui={ui} />
          <span className="car-open-cue">{ui.clickOpen} ↗</span>
        </button>
        <div className="car-slot car-next"><Frame slide={at(1)} active={false} interactive={false} lang={lang} ui={ui} /></div>
      </div>
      <div className="car-ctrl">
        <button onClick={() => go(-1)} aria-label="prev"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><path d="M15 6l-6 6 6 6" /></svg></button>
        <div className="car-meta">
          <b style={{ color: at(0).p.accent2 }}>{at(0).p.name}</b>
          <span>{at(0).mode === "phone" ? ui.phoneV : ui.webV} · {String(i + 1).padStart(2, "0")}/{String(n).padStart(2, "0")}</span>
        </div>
        <button onClick={() => go(1)} aria-label="next"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><path d="M9 6l6 6-6 6" /></svg></button>
      </div>
      <div className="car-dots">
        {slides.map((s, k) => <button key={k} className={"cdot" + (k === i ? " on" : "")} onClick={() => setI(k)} style={k === i ? { background: s.p.accent2 } : {}} />)}
      </div>
    </div>
  );
}

/* ---------- Big "Ver Mais" page (fullscreen, with tech stacks) ---------- */
function BigCarousel({ lang, ui, startIndex, onClose }) {
  const slides = KP.SLIDES;
  const n = slides.length;
  const [i, setI] = useStateK(startIndex || 0);
  const [show, setShow] = useStateK(false);
  useEffectK(() => {
    const r = requestAnimationFrame(() => setShow(true));
    const onKey = (e) => { if (e.key === "Escape") onClose(); if (e.key === "ArrowLeft") setI((v) => (v - 1 + n) % n); if (e.key === "ArrowRight") setI((v) => (v + 1) % n); };
    window.addEventListener("keydown", onKey);
    return () => { window.removeEventListener("keydown", onKey); cancelAnimationFrame(r); };
  }, [n, onClose]);
  const slide = slides[i];
  const p = slide.p;
  const stack = slide.mode === "phone" ? p.mobileStack : p.webStack;
  const go = (d) => setI((v) => (v + d + n) % n);

  return (
    <div className={"big" + (show ? " show" : "")} style={{ "--a": p.accent, "--a2": p.accent2 }}>
      <div className="big-ambient" />
      <header className="big-top">
        <div className="big-id">
          <span className="big-code">{String(i + 1).padStart(2, "0")} / {String(n).padStart(2, "0")}</span>
          <span className="big-title" style={{ color: p.accent2 }}>{p.name}</span>
          <span className="big-sector">{p.sector[lang]}</span>
        </div>
        <div className="big-actions">
          <a className="big-link" href={p.web} target="_blank" rel="noopener">{ui.openSite} ↗</a>
          <button className="fs-close" onClick={onClose}><span>{ui.close}</span><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg></button>
        </div>
      </header>

      <div className="big-stage">
        <button className="big-nav big-prev" onClick={() => go(-1)} aria-label="prev"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M15 6l-6 6 6 6" /></svg></button>
        <div className="big-frame-wrap" key={p.id + slide.mode}>
          <Frame slide={slide} active={true} interactive={true} lang={lang} ui={ui} big={true} />
          <span className="big-mode">{slide.mode === "phone" ? ui.phoneV : ui.webV}</span>
        </div>
        <button className="big-nav big-next" onClick={() => go(1)} aria-label="next"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M9 6l6 6-6 6" /></svg></button>
      </div>

      <div className="big-foot">
        <div className="big-stack">
          <span className="big-stack-label">{ui.stacksLabel}</span>
          {stack
            ? <span className="big-chips">{stack.split(" · ").map((s, k) => <span key={k} className="big-chip">{s}</span>)}</span>
            : <span className="big-chips"><span className="big-chip dim">—</span></span>}
        </div>
        <div className="big-dots">
          {slides.map((s, k) => <button key={k} className={"cdot" + (k === i ? " on" : "")} onClick={() => setI(k)} style={k === i ? { background: s.p.accent2 } : {}} />)}
        </div>
      </div>
    </div>
  );
}

window.ENKIICarousel = { Carousel, BigCarousel, StatusList };
