/* PIXYcal — Team section with per-member photo upload + manual positioning.
   Photos are stored in localStorage (large blobs don't belong in source JSON).
   Per-member position / scale / name / role live in tweaks. */
const { useState: useStateT, useEffect: useEffectT, useRef: useRefT } = React;

const TEAM_PHOTO_LS_PREFIX = "pxTeamPhoto_";

function useTeamPhoto(memberId) {
  const [dataUrl, setDataUrl] = useStateT(() => {
    try {return localStorage.getItem(TEAM_PHOTO_LS_PREFIX + memberId) || "";} catch {return "";}
  });
  useEffectT(() => {
    const onStorage = (e) => {
      if (e.key === TEAM_PHOTO_LS_PREFIX + memberId) setDataUrl(e.newValue || "");
    };
    const onCustom = (e) => {
      if (e.detail?.id === memberId) setDataUrl(e.detail.dataUrl || "");
    };
    window.addEventListener("storage", onStorage);
    window.addEventListener("px-team-photo-change", onCustom);
    return () => {
      window.removeEventListener("storage", onStorage);
      window.removeEventListener("px-team-photo-change", onCustom);
    };
  }, [memberId]);
  const set = (val) => {
    try {
      if (val) localStorage.setItem(TEAM_PHOTO_LS_PREFIX + memberId, val);else
      localStorage.removeItem(TEAM_PHOTO_LS_PREFIX + memberId);
    } catch {}
    setDataUrl(val || "");
    window.dispatchEvent(new CustomEvent("px-team-photo-change", { detail: { id: memberId, dataUrl: val } }));
  };
  return [dataUrl, set];
}

function TeamCard({ member, t }) {
  const [photo] = useTeamPhoto(member.id);
  const m = t.team[member.id] || {};
  const effectivePhoto = photo || member.defaultPhoto || "";
  const name = m.name ?? member.defaultName;
  const fullName = m.fullName ?? member.defaultFullName;
  const role = m.role ?? member.defaultRole;
  const objX = m.x ?? member.defaultX ?? 50;
  const objY = m.y ?? member.defaultY ?? 30;
  const scale = m.scale ?? member.defaultScale ?? 1;

  return (
    <article style={{
      position: "relative", display: "flex", flexDirection: "column",
      background: "var(--px-surface-2)", border: "1px solid var(--px-line)",
      borderRadius: "var(--px-radius)", overflow: "hidden",
      transition: "border-color 200ms var(--px-easing), transform 200ms var(--px-easing)"
    }}
    onMouseEnter={(e) => {e.currentTarget.style.borderColor = "var(--px-line-strong)";e.currentTarget.style.transform = "translateY(-3px)";}}
    onMouseLeave={(e) => {e.currentTarget.style.borderColor = "var(--px-line)";e.currentTarget.style.transform = "none";}}>
      <div style={{
        position: "relative", overflow: "hidden",
        borderBottom: "1px solid var(--px-line)",
        aspectRatio: "4 / 5",
        background: "var(--px-surface-3)"
      }}>
        {effectivePhoto ?
        <img src={effectivePhoto} alt={fullName} loading="lazy" decoding="async"
        style={{
          width: "100%",
          height: "100%",
          objectFit: "cover",
          objectPosition: `${objX}% ${objY}%`,
          transform: `scale(${scale})`,
          transformOrigin: `${objX}% ${objY}%`,
          display: "block",
          transition: "object-position 120ms linear, transform 120ms linear"
        }} /> :

        <div style={{
          position: "absolute", inset: 0,
          display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 12
        }}>
            <svg viewBox="0 0 24 24" width={48} height={48} fill="none" stroke="currentColor" strokeWidth={1.6}
          strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
          style={{ color: "var(--px-line-strong)" }}>
              <circle cx="12" cy="8" r="4" />
              <path d="M4 21a8 8 0 0 1 16 0" />
            </svg>
            <span style={{
            fontFamily: "var(--px-font-mono)", fontSize: 10, fontWeight: 700,
            letterSpacing: "0.14em", textTransform: "uppercase",
            color: "var(--px-text-muted)"
          }}>Foto brzy</span>
          </div>
        }
      </div>
      <div style={{ padding: "22px 22px 26px" }}>
        <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
          <h3 style={{ margin: 0, fontFamily: "var(--px-font-display)", fontWeight: 700, fontSize: 28, letterSpacing: "-0.03em", color: "var(--px-text-strong)" }}>
            {name}
          </h3>
          {fullName && fullName !== name &&
          <span style={{ fontFamily: "var(--px-font-mono)", fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--px-text-muted)" }}>
              {fullName}
            </span>
          }
        </div>
        <p style={{
          margin: "8px 0 0", fontFamily: "var(--px-font-sans)", fontSize: 14, fontWeight: 600,
          background: "var(--px-gradient)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent",
          display: "inline-block"
        }}>
          {role}
        </p>
      </div>
    </article>);

}

const TEAM_MEMBERS = [
{ id: "m1", defaultName: "Vali", defaultFullName: "Valerij Lejzo", defaultRole: "Systémy & automatizace", defaultPhoto: "assets/team/vali.jpg", defaultX: 50, defaultY: 22, defaultScale: 1.12 },
{ id: "m2", defaultName: "Honza", defaultFullName: "Jan Halouzka", defaultRole: "Strategie & PPC", defaultPhoto: "assets/team/honza.jpg", defaultX: 22, defaultY: 48, defaultScale: 1.2 },
{ id: "m3", defaultName: "Filip", defaultFullName: "Filip Janík", defaultRole: "Kreativa & exekuce", defaultPhoto: "assets/team/filip.jpg", defaultX: 0, defaultY: 36, defaultScale: 1.14 },
{ id: "m4", defaultName: "Patricie", defaultFullName: "Patricie", defaultRole: "Doplníme brzy", defaultPhoto: "", defaultX: 50, defaultY: 30, defaultScale: 1 }];


function TeamSection({ t }) {
  const Reveal = window.Reveal;
  const Eyebrow = window.Eyebrow;
  return (
    <section id="tym" style={{
      paddingBlock: "calc(112px * var(--px-density))",
      borderBottom: "1px solid var(--px-line)",
      background: "var(--px-surface-0)"
    }}>
      <div className="px-container">
        <Reveal style={{ textAlign: "center", marginInline: "auto", marginBottom: 56 }}>
          {t.teamEyebrow ? <Eyebrow>{t.teamEyebrow}</Eyebrow> : null}
          <h2 style={{
            margin: "16px 0 16px", fontFamily: "var(--px-font-display)", fontWeight: 700,
            fontSize: "clamp(32px, 4.4vw, 56px)", lineHeight: 1.02, letterSpacing: "-0.04em",
            color: "var(--px-text-strong)", textWrap: "balance", textAlign: "center"
          }}>
            {t.teamHeadline}{" "}
            <span style={{ background: "var(--px-gradient)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent" }}>
              {t.teamHeadlineAccent}
            </span>
          </h2>
          {t.teamSubtitle &&
          <p style={{ margin: "0 auto", maxWidth: 580, fontSize: 17, lineHeight: 1.55, color: "var(--px-text-muted)" }}>
              {t.teamSubtitle}
            </p>
          }
        </Reveal>
        <Reveal>
          <div className="px-team-grid">
            {TEAM_MEMBERS.map((m) => <TeamCard key={m.id} member={m} t={t} />)}
          </div>
        </Reveal>
      </div>
      <style>{`
        .px-team-grid { display: grid; gap: 14px; grid-template-columns: repeat(2, 1fr); }
        @media (min-width: 1024px){ .px-team-grid { grid-template-columns: repeat(4, 1fr); gap: 18px; } }
      `}</style>
    </section>);

}

/* Per-member tweak controls — exported via window for use in the panel. */
function TeamPhotoControls({ member, t, setTweak }) {
  const [photo, setPhoto] = useTeamPhoto(member.id);
  const fileRef = useRefT(null);
  const m = t.team?.[member.id] || {};
  const setM = (patch) => {
    const next = { ...(t.team || {}), [member.id]: { ...m, ...patch } };
    setTweak("team", next);
  };
  const onFile = (e) => {
    const f = e.target.files?.[0];if (!f) return;
    const reader = new FileReader();
    reader.onload = () => {
      // Resize before saving to keep localStorage small (max 900px wide, JPEG 0.85).
      const img = new Image();
      img.onload = () => {
        const max = 900;
        const ratio = Math.min(1, max / img.width);
        const w = Math.round(img.width * ratio);
        const h = Math.round(img.height * ratio);
        const c = document.createElement("canvas");
        c.width = w; c.height = h;
        c.getContext("2d").drawImage(img, 0, 0, w, h);
        setPhoto(c.toDataURL("image/jpeg", 0.85));
      };
      img.src = String(reader.result);
    };
    reader.readAsDataURL(f);
  };
  const name = m.name ?? member.defaultName;
  const fullName = m.fullName ?? member.defaultFullName;
  const role = m.role ?? member.defaultRole;
  return (
    <>
      <div className="twk-sect">{member.defaultName}{photo ? " ✓" : ""}</div>
      <TweakText label="Display name" value={name} onChange={(v) => setM({ name: v })} />
      <TweakText label="Full name" value={fullName} onChange={(v) => setM({ fullName: v })} />
      <TweakText label="Role" value={role} onChange={(v) => setM({ role: v })} />
      <div className="twk-row">
        <div className="twk-lbl"><span>Photo</span></div>
        <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
          <button type="button" className="twk-btn" onClick={() => fileRef.current?.click()}>
            {photo ? "Replace" : "Upload"}
          </button>
          {photo &&
          <button type="button" className="twk-btn secondary" onClick={() => setPhoto("")}>
              Clear
            </button>
          }
          <input ref={fileRef} type="file" accept="image/*" style={{ display: "none" }} onChange={onFile} />
        </div>
      </div>
      <TweakSlider label="Photo X" value={m.x ?? member.defaultX ?? 50} min={0} max={100} step={1} unit="%"
      onChange={(v) => setM({ x: v })} />
      <TweakSlider label="Photo Y" value={m.y ?? member.defaultY ?? 30} min={0} max={100} step={1} unit="%"
      onChange={(v) => setM({ y: v })} />
      <TweakSlider label="Zoom" value={m.scale ?? member.defaultScale ?? 1} min={1} max={2} step={0.02}
      onChange={(v) => setM({ scale: v })} />
    </>);

}

Object.assign(window, { TeamSection, TeamPhotoControls, TEAM_MEMBERS });