// constructor.jsx — team photo nickname constructor
const { useState, useRef, useEffect: useEffectC } = React;

/* Character anchor positions over team-photo.jpg
   x, y are in % of image (0..100). y is where the TOP of the nickname label sits. */
const ANCHORS = [
  { id: 1, x: 48.0, y: 42.0 },  // bandana AK guy
  { id: 2, x: 53.0, y: 54.0 },  // crouching masked (front)
  { id: 3, x: 58.0, y: 40.0 },  // mask AK pointed up
  { id: 4, x: 62.0, y: 41.0 },  // astronaut centerpiece
  { id: 5, x: 67.0, y: 37.0 },  // tall helmet
  { id: 6, x: 74.0, y: 54.0 },  // kneeling helmet
  { id: 7, x: 82.0, y: 40.0 },  // tank-top w/ block helmet
  { id: 8, x: 86.0, y: 55.0 },  // crouching gas-mask
  { id: 9, x: 92.0, y: 42.0 },  // far right bald
];

const PRESET_NAMES = [
  "VOLK", "GHOST", "RUST", "ASTRO",
  "TANK", "BLADE", "WIRE", "SCRAP", "HEX"
];

function Constructor() {
  const [names, setNames] = useState(() => ANCHORS.map(() => ""));
  const [disabled, setDisabled] = useState(() => new Set());
  const [toast, setToast] = useState(null);
  const stageRef = useRef(null);
  const imgRef = useRef(null);

  // Scale label sizes proportional to stage width
  useEffectC(() => {
    const el = stageRef.current;
    if (!el) return;
    const update = () => {
      const w = el.offsetWidth;
      const s = Math.max(0.55, Math.min(1.15, w / 1440));
      el.style.setProperty("--s", s);
    };
    update();
    const ro = new ResizeObserver(update);
    ro.observe(el);
    window.addEventListener("resize", update);
    return () => { ro.disconnect(); window.removeEventListener("resize", update); };
  }, []);

  const setName = (i, v) => {
    const next = names.slice();
    next[i] = v.toUpperCase().slice(0, 14);
    setNames(next);
  };

  const removeRow = (id) => {
    const next = new Set(disabled);
    next.add(id);
    setDisabled(next);
  };
  const restoreRow = (id) => {
    const next = new Set(disabled);
    next.delete(id);
    setDisabled(next);
  };

  const fillPresets = () => {
    setNames(PRESET_NAMES.slice(0, ANCHORS.length));
  };
  const clearAll = () => setNames(ANCHORS.map(() => ""));
  const resetDefaults = () => {
    setNames(ANCHORS.map(() => ""));
    setDisabled(new Set());
  };

  const showToast = (msg) => {
    setToast(msg);
    setTimeout(() => setToast(null), 1800);
  };

  const handleDownload = async () => {
    const img = imgRef.current;
    if (!img || !img.complete) {
      showToast("Loading...");
      return;
    }
    const w = img.naturalWidth;
    const h = img.naturalHeight;
    const canvas = document.createElement("canvas");
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, w, h);

    const fontSize = Math.round(h * 0.032);
    ctx.font = `700 ${fontSize}px "Space Grotesk", system-ui, sans-serif`;
    ctx.textBaseline = "middle";
    const dotR = fontSize * 0.36;
    const gap = fontSize * 0.5;
    const padX = fontSize * 0.5;
    const padY = fontSize * 0.32;

    ANCHORS.forEach((a, i) => {
      if (disabled.has(a.id)) return;
      const text = names[i];
      if (!text) return;
      const tw = ctx.measureText(text).width;
      const blockW = dotR * 2 + gap + tw + padX * 2;
      const blockH = fontSize + padY * 2;
      const cx = (a.x / 100) * w;
      const cy = (a.y / 100) * h;
      const x0 = cx - blockW / 2;
      const y0 = cy;

      ctx.fillStyle = "rgba(11,12,13,0.65)";
      roundRect(ctx, x0, y0, blockW, blockH, 4);
      ctx.fill();
      ctx.strokeStyle = "rgba(110,255,58,0.75)";
      ctx.lineWidth = Math.max(1, fontSize * 0.06);
      roundRect(ctx, x0, y0, blockW, blockH, 4);
      ctx.stroke();

      const dotCx = x0 + padX + dotR;
      const dotCy = y0 + blockH / 2;
      const glow = ctx.createRadialGradient(dotCx, dotCy, 0, dotCx, dotCy, dotR * 3);
      glow.addColorStop(0, "rgba(110,255,58,0.7)");
      glow.addColorStop(1, "rgba(110,255,58,0)");
      ctx.fillStyle = glow;
      ctx.beginPath();
      ctx.arc(dotCx, dotCy, dotR * 3, 0, Math.PI * 2);
      ctx.fill();
      ctx.fillStyle = "#6EFF3A";
      ctx.beginPath();
      ctx.arc(dotCx, dotCy, dotR, 0, Math.PI * 2);
      ctx.fill();

      ctx.save();
      ctx.fillStyle = "#9EFF6B";
      ctx.shadowColor = "rgba(110,255,58,0.85)";
      ctx.shadowBlur = fontSize * 0.6;
      ctx.fillText(text, dotCx + dotR + gap, dotCy);
      ctx.restore();
    });

    ctx.font = `500 ${Math.round(h * 0.014)}px "JetBrains Mono", monospace`;
    ctx.fillStyle = "rgba(255,255,255,0.45)";
    ctx.fillText("OXIDE · TEAM", w * 0.018, h * 0.96);

    canvas.toBlob((blob) => {
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      const stamp = new Date().toISOString().slice(0, 10);
      a.download = `oxide-team-${stamp}.png`;
      a.click();
      setTimeout(() => URL.revokeObjectURL(url), 1000);
      showToast("Downloaded");
    }, "image/png");
  };

  const activeAnchors = ANCHORS.filter((a) => !disabled.has(a.id));
  const filledCount = activeAnchors.filter((a) => names[ANCHORS.indexOf(a)]).length;
  const totalActive = activeAnchors.length;

  return (
    <div>
      <div className="page-head">
        <div>
          <h1>TEAM <span className="h1-accent">/</span> CONSTRUCTOR</h1>
          <p className="page-sub">Type in your friends' names and make a team photo.</p>
        </div>
        <p>Enter nicknames above each fighter and save your clan's team photo.</p>
      </div>

      <div className="filterbar">
        <span className="label">PROGRESS</span>
        <span className="mono" style={{color: filledCount === totalActive && totalActive > 0 ? "var(--friend)" : "var(--fg)"}}>
          {filledCount.toString().padStart(2, "0")} / {totalActive.toString().padStart(2, "0")}
        </span>
        {disabled.size > 0 && (
          <>
            <span className="label" style={{marginLeft: 16}}>HIDDEN</span>
            <span className="mono" style={{color: "var(--fg-mute)"}}>{disabled.size.toString().padStart(2, "0")}</span>
          </>
        )}
        <div className="spacer"></div>
        <span className="sort">RESOLUTION&nbsp;<span>3168 × 1344</span></span>
      </div>

      <div className="constructor-wrap">
        <div className="stage-frame" ref={stageRef}>
          <img
            ref={imgRef}
            className="stage-bg"
            src="assets/team-photo.jpg"
            alt="Team photo"
            crossOrigin="anonymous"
          />
          {ANCHORS.map((a, i) => {
            if (disabled.has(a.id)) return null;
            return (
              <div
                key={a.id}
                className="tag-input"
                style={{
                  left: a.x + "%",
                  top: a.y + "%",
                  transform: "translate(-50%, 0)",
                }}
              >
                <span className="tag-dot"></span>
                <input
                  className="tag-field"
                  type="text"
                  maxLength={14}
                  placeholder={"P" + a.id.toString().padStart(2, "0")}
                  value={names[i]}
                  onChange={(e) => setName(i, e.target.value)}
                />
                <button
                  className="tag-remove"
                  title="Remove this slot"
                  onClick={() => removeRow(a.id)}
                  aria-label="remove"
                >×</button>
              </div>
            );
          })}
        </div>

        <aside className="panel">
          <h3>Constructor</h3>
          <div className="panel-sub">Steps · 003</div>

          <div className="step"><span className="n">01</span>Click the field above a fighter and type a nickname.</div>
          <div className="step"><span className="n">02</span>Up to 14 characters. Uppercase only.</div>
          <div className="step"><span className="n">03</span>Hit “Download” — PNG at original resolution.</div>

          <div className="field-list">
            {ANCHORS.map((a, i) => {
              const isOff = disabled.has(a.id);
              return (
                <div className={"field-row " + (isOff ? "off" : "")} key={a.id}>
                  <span className="idx mono">{a.id.toString().padStart(2, "0")}</span>
                  <span className="row-dot"></span>
                  <input
                    type="text"
                    placeholder={"PLAYER " + a.id.toString().padStart(2, "0")}
                    value={names[i]}
                    maxLength={14}
                    onChange={(e) => setName(i, e.target.value)}
                    disabled={isOff}
                  />
                  {isOff ? (
                    <button
                      className="row-btn restore"
                      title="Restore slot"
                      onClick={() => restoreRow(a.id)}
                      aria-label="restore"
                    >+</button>
                  ) : (
                    <button
                      className="row-btn remove"
                      title="Remove slot"
                      onClick={() => removeRow(a.id)}
                      aria-label="remove"
                    >×</button>
                  )}
                </div>
              );
            })}
          </div>

          <div className="actions">
            <button onClick={handleDownload}>
              <svg viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.6">
                <path d="M6 1v8M2 6l4 4 4-4M1 11h10" />
              </svg>
              Download PNG
            </button>
            <button className="ghost" onClick={fillPresets}>Fill with example</button>
            <button className="ghost" onClick={clearAll}>Clear names</button>
            <button className="ghost" onClick={resetDefaults}>Reset to defaults</button>
          </div>
        </aside>
      </div>

      {toast && <div className="toast">{toast}</div>}
    </div>
  );
}

function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.lineTo(x + w - r, y);
  ctx.quadraticCurveTo(x + w, y, x + w, y + r);
  ctx.lineTo(x + w, y + h - r);
  ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
  ctx.lineTo(x + r, y + h);
  ctx.quadraticCurveTo(x, y + h, x, y + h - r);
  ctx.lineTo(x, y + r);
  ctx.quadraticCurveTo(x, y, x + r, y);
  ctx.closePath();
}

window.Constructor = Constructor;
