// Canvas — renders the actual session photo, the warp/heal results,
// and overlays. All images are <img> tags served by /api/image/...

const Canvas = ({ ctx }) => {
  const { state, set } = ctx;
  const [splitPos, setSplitPos] = React.useState(50);
  const [pressing, setPressing] = React.useState(false);

  const handleSplitDrag = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const move = (ev) => {
      const x = ((ev.clientX - rect.left) / rect.width) * 100;
      setSplitPos(Math.max(0, Math.min(100, x)));
    };
    const up = () => {
      window.removeEventListener("mousemove", move);
      window.removeEventListener("mouseup", up);
    };
    window.addEventListener("mousemove", move);
    window.addEventListener("mouseup", up);
  };

  const session = state.session;
  if (!session) return <EmptyCanvas ctx={ctx} />;

  // Resolve the "projection" image — preference: active heal result, else live warp, else original
  const activeResult = state.results.find(r => r.id === state.activeResult);
  const projectionUrl =
    activeResult && activeResult.kind !== "original" ? activeResult.url
    : state.warpImageUrl
    || session.image_url;

  const projectionLabel =
    activeResult && activeResult.kind === "heal" ? "Photoreal heal"
    : state.warpImageUrl ? "Warp preview"
    : "Baseline";

  const originalUrl = session.image_url;
  const compareMode = state.compareMode;

  return (
    <div className="canvas-wrap">
      <div className="canvas-toolbar">
        <div className="canvas-tabs">
          {[["toggle", "Hold to compare"], ["split", "Split slider"], ["onion", "Onion-skin"], ["side", "Side-by-side"]].map(([m, label]) => (
            <button
              key={m}
              className={`canvas-tab ${compareMode === m ? "active" : ""}`}
              onClick={() => set({ compareMode: m })}
            >{label}</button>
          ))}
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          <div className="mono-tiny">VIEW · {session.view.tag} · yaw {session.view.yaw}°</div>
        </div>
      </div>

      <div className="canvas-stage">
        {compareMode === "side" && (
          <div style={{ display: "flex", gap: 24, alignItems: "center" }}>
            <PhotoFrame label="Baseline" mono="ORIGINAL" sub="T0" view={session.view} url={originalUrl} />
            <PhotoFrame label={projectionLabel} mono={(state.warping ? "COMPUTING" : "PROJECTION")} sub={state.warpKey || "—"} view={session.view} url={projectionUrl} overlays={state.overlays} />
          </div>
        )}

        {compareMode === "split" && (
          <div className="face-frame" onMouseDown={handleSplitDrag} style={{ cursor: "ew-resize" }}>
            <FaceCorners view={session.view} label="Baseline / Projection" sub="↔" mono="DRAG TO COMPARE" />
            <img src={originalUrl} className="canvas-img" alt="original" style={{ clipPath: `inset(0 ${100 - splitPos}% 0 0)` }} />
            <img src={projectionUrl} className="canvas-img" alt="projection" style={{ clipPath: `inset(0 0 0 ${splitPos}%)` }} />
            <div className="split-handle" style={{ left: `${splitPos}%` }} />
            <div className="split-label" style={{ left: 14 }}>Before</div>
            <div className="split-label" style={{ right: 14 }}>After</div>
          </div>
        )}

        {compareMode === "onion" && (
          <div className="face-frame">
            <FaceCorners view={session.view} label="Onion-skin" sub="0.5 opacity" mono="OVERLAY" />
            <img src={originalUrl} className="canvas-img" alt="original" style={{ opacity: 0.5 }} />
            <img src={projectionUrl} className="canvas-img" alt="projection" />
          </div>
        )}

        {compareMode === "toggle" && (
          <div
            className="face-frame"
            onMouseDown={() => setPressing(true)}
            onMouseUp={() => setPressing(false)}
            onMouseLeave={() => setPressing(false)}
            style={{ cursor: "pointer", userSelect: "none" }}
          >
            <FaceCorners
              view={session.view}
              label={pressing ? "Baseline" : projectionLabel}
              sub={pressing ? "T0" : (state.warpKey || "")}
              mono={pressing ? "HOLD · ORIGINAL" : (state.warping ? "COMPUTING…" : "RELEASE · PROJECTION")}
            />
            <img src={pressing ? originalUrl : projectionUrl} className="canvas-img" alt="canvas" />
          </div>
        )}

        {state.healing && <HealProgress />}
      </div>

      <div className="canvas-footer">
        <div>
          <span className="mono-tiny">SESSION · {session.session_id}</span>
        </div>
        <div className="right">
          <span>VIEW · <b>{session.view.tag}</b></span>
          <span>LANDMARKS · <b>{session.landmarks_count}</b></span>
          <span>IPD · <b>{session.measurements.ipd_px}px</b></span>
          <span>SYMMETRY · <b>{session.measurements.symmetry}</b></span>
        </div>
      </div>
    </div>
  );
};

const EmptyCanvas = ({ ctx }) => (
  <div className="canvas-wrap">
    <div className="canvas-toolbar">
      <div className="mono-tiny">NO SESSION · Upload a portrait or pick a sample</div>
    </div>
    <div className="canvas-stage">
      <div className="face-frame" style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
        <div style={{ textAlign: "center", padding: 40 }}>
          <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 36, color: "var(--ink-3)", lineHeight: 1.1, marginBottom: 14 }}>
            Begin with a <em>portrait</em>.
          </div>
          <div className="mono-tiny" style={{ color: "var(--ink-3)" }}>
            Drag &amp; drop, browse, or pick a sample on the left.
          </div>
        </div>
      </div>
    </div>
    <div className="canvas-footer">
      <div><span className="mono-tiny">NO SESSION</span></div>
      <div className="right">
        <span>STATUS · <b>ready</b></span>
      </div>
    </div>
  </div>
);

const PhotoFrame = ({ url, label, mono, sub, view, overlays }) => (
  <div className="face-frame" style={{ width: 380 }}>
    <FaceCorners view={view} label={label} sub={sub} mono={mono} />
    <img src={url} className="canvas-img" alt={label} />
  </div>
);

const FaceCorners = ({ view, label, sub, mono }) => (
  <>
    <div className="face-corner tl">
      <span>{mono}</span>
      <span className="big">{label}</span>
    </div>
    <div className="face-corner tr"><span>{sub}</span></div>
    <div className="face-corner bl"><span>VIEW · {(view.tag || view).toString().toUpperCase()}</span></div>
    <div className="face-corner br"><span>{view.yaw != null ? `YAW ${view.yaw}°` : ""}</span></div>
  </>
);

const HealProgress = () => {
  const [progress, setProgress] = React.useState(0.05);
  React.useEffect(() => {
    let raf;
    const start = Date.now();
    const tick = () => {
      const t = (Date.now() - start) / 30000;
      setProgress(Math.min(0.92, t));
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);
  const elapsed = progress * 30;
  const stage = progress < 0.15 ? 0 : progress < 0.85 ? 1 : 2;
  return (
    <div className="heal-progress-overlay">
      <div className="heal-progress">
        <div className="stage">
          {stage === 0 ? "Stage 01 · Queued" : stage === 1 ? "Stage 02 · Generating" : "Stage 03 · Blending"}
        </div>
        <div className="title">Synthesizing your <em>photoreal heal</em>.</div>
        <div className="bar"><div style={{ width: `${progress * 100}%` }} /></div>
        <div className="steps">
          <span className={stage >= 1 ? "done" : "active"}>QUEUED</span>
          <span className={stage >= 2 ? "done" : (stage === 1 ? "active" : "")}>GENERATING</span>
          <span className={stage === 2 ? "active" : ""}>BLENDING</span>
        </div>
        <div className="mono-tiny" style={{ marginTop: 14 }}>
          fal.ai · flux-general/inpainting · diffusion can take up to a minute
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { Canvas, FaceCorners, HealProgress, EmptyCanvas });
