/* SeaVIN — Shared components */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ============================================
   Logo
   ============================================ */
function Logo({ compact = false }) {
  return (
    <a href="index.html" className="logo" aria-label="SeaVIN">
      <svg className="logo__mark" viewBox="0 0 32 32" fill="none" aria-hidden="true">
        {/* hull + keel mark, like a punch-stamp on a boat */}
        <path d="M3 18 L16 4 L29 18 L16 28 Z" stroke="currentColor" strokeWidth="1.5" fill="none"/>
        <path d="M9 18 L16 11 L23 18 L16 24 Z" stroke="currentColor" strokeWidth="1" fill="none"/>
        <circle cx="16" cy="18" r="1.5" fill="currentColor"/>
      </svg>
      {!compact && (
        <span className="logo__word">Sea<em>VIN</em></span>
      )}
    </a>
  );
}

/* ============================================
   Nav
   ============================================ */
function Nav({ active, t, lang, onLang, minimal = false }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const links = [
    { id: "how", label: t.nav.how, href: "how-it-works.html" },
    { id: "report", label: t.nav.report, href: "sample-report.html" },
    { id: "pricing", label: t.nav.pricing, href: "pricing.html" },
    { id: "surveyors", label: t.nav.surveyors, href: "surveyors.html" },
    { id: "about", label: t.nav.about, href: "about.html" },
  ];
  if (minimal) {
    return (
      <>
        <header className={`nav nav--minimal ${scrolled ? "is-scrolled" : ""}`}>
          <div className="shell nav__inner">
            <Logo />
          </div>
        </header>
        <div className="nav__spacer" aria-hidden="true" />
      </>
    );
  }
  return (
    <>
    <header className={`nav ${scrolled ? "is-scrolled" : ""}`}>
      <div className="shell nav__inner">
        <Logo />
        <nav className="nav__links">
          {links.map((l) => (
            <a
              key={l.id}
              href={l.href}
              className={`nav__link ${active === l.id ? "is-active" : ""}`}
            >
              {l.label}
            </a>
          ))}
        </nav>
        <div className="nav__cta">
          {(typeof window !== "undefined" && window.SeaVAuth?.currentUser())
            ? <a href="dashboard.html" className="nav__link" style={{ marginRight: 4 }}>
                {window.SeaVAuth.currentUser().firstName || t.nav.login}
              </a>
            : <a href="login.html" className="nav__link" style={{ marginRight: 4 }}>{t.nav.login}</a>
          }
          <a href="checkout.html" className="btn btn--sm">{t.nav.start}</a>
        </div>
      </div>
    </header>
    <div className="nav__spacer" aria-hidden="true" />
    </>
  );
}

/* ============================================
   Footer
   ============================================ */
function Footer({ t, lang }) {
  const year = 2026;
  return (
    <footer className="footer">
      <div className="shell">
        <div className="footer__grid">
          <div className="footer__col">
            <Logo />
            <p style={{
              marginTop: 18,
              fontSize: 13,
              color: "var(--ink-mute)",
              maxWidth: "32ch",
              lineHeight: 1.55
            }}>
              {t.footer.tag}
            </p>
            <div style={{ marginTop: 18, display: "flex", gap: 8 }}>
              <span className="stamp">SeaVIN · Verified</span>
            </div>
          </div>
          <div className="footer__col">
            <h4>{t.footer.col_product}</h4>
            <a href="how-it-works.html">{t.nav.how}</a>
            <a href="sample-report.html">{t.nav.report}</a>
            <a href="pricing.html">{t.nav.pricing}</a>
            <a href="checkout.html">{t.nav.start}</a>
          </div>
          <div className="footer__col">
            <h4>{t.footer.col_company}</h4>
            <a href="about.html">{t.nav.about}</a>
            <a href="surveyors.html">{t.nav.surveyors}</a>
            <a href="surveyors-signup.html">{lang === "it" ? "Area periti" : "For surveyors"}</a>
            <a href="#">{lang === "it" ? "Contatti" : "Contact"}</a>
          </div>
          <div className="footer__col">
            <h4>{t.footer.col_resources}</h4>
            <a href="#">{lang === "it" ? "Glossario HIN" : "HIN glossary"}</a>
            <a href="#">{lang === "it" ? "Verifica documentale" : "Document verification"}</a>
            <a href="#">{lang === "it" ? "Guide acquisto" : "Buying guides"}</a>
            <a href="#">API</a>
          </div>
          <div className="footer__col">
            <h4>{t.footer.col_legal}</h4>
            <a href="#">{lang === "it" ? "Termini" : "Terms"}</a>
            <a href="#">Privacy</a>
            <a href="#">Cookie</a>
            <a href="#">GDPR</a>
          </div>
        </div>
        <div className="footer__bottom">
          <span>© {year} SeaVIN S.r.l. · P.IVA 12345670962</span>
          <span>SeaVIN Verification System · ISO 27001</span>
        </div>
      </div>
    </footer>
  );
}

/* ============================================
   Tweaks panel
   ============================================ */
function TweaksPanel({ cfg, setCfg }) {
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const handler = (e) => {
      if (e.data?.type === "__activate_edit_mode") setOpen(true);
      if (e.data?.type === "__deactivate_edit_mode") setOpen(false);
    };
    window.addEventListener("message", handler);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", handler);
  }, []);

  const set = (k, v) => {
    const next = { ...cfg, [k]: v };
    setCfg(next);
    try { localStorage.setItem("seavin.cfg", JSON.stringify(next)); } catch (e) {}
    window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [k]: v } }, "*");
  };

  if (!open) return null;

  const rows = [
    { k: "palette", label: "Palette", opts: [
      { v: "cream", l: "Cream" },
      { v: "navy", l: "Navy" },
      { v: "paper", l: "Paper" },
    ]},
    { k: "theme", label: "Theme", opts: [
      { v: "light", l: "Light" },
      { v: "dark", l: "Dark" },
    ]},
    { k: "typeset", label: "Typography", opts: [
      { v: "editorial", l: "Editorial" },
      { v: "technical", l: "Technical" },
    ]},
    { k: "heroLayout", label: "Hero layout", opts: [
      { v: "split", l: "Split" },
      { v: "stacked", l: "Stacked" },
      { v: "centered", l: "Centered" },
    ]},
    { k: "tone", label: "Copy tone", opts: [
      { v: "reassuring", l: "Rassicurante" },
      { v: "technical", l: "Tecnico" },
      { v: "urgent", l: "Urgente" },
    ]},
    { k: "lang", label: "Language", opts: [
      { v: "it", l: "IT" },
      { v: "en", l: "EN" },
    ]},
  ];

  return (
    <div className="tweaks-panel">
      <div className="tweaks-panel__head">
        <span className="tweaks-panel__title">Tweaks</span>
        <button className="tweaks-panel__close" onClick={() => setOpen(false)}>×</button>
      </div>
      {rows.map((r) => (
        <div key={r.k} className="tweak-row">
          <span className="tweak-row__label">{r.label}</span>
          <div className="tweak-opts">
            {r.opts.map((o) => (
              <button
                key={o.v}
                className={`tweak-opt ${cfg[r.k] === o.v ? "is-active" : ""}`}
                onClick={() => set(r.k, o.v)}
              >
                {o.l}
              </button>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

/* ============================================
   Apply config to <html>
   ============================================ */
function useApplyConfig(cfg) {
  useEffect(() => {
    const html = document.documentElement;
    html.setAttribute("data-palette", cfg.palette);
    html.setAttribute("data-theme", cfg.theme);
    html.setAttribute("data-typeset", cfg.typeset);
  }, [cfg]);
}

/* ============================================
   Config loader w/ defaults
   ============================================ */
function useConfig(defaults) {
  const [cfg, setCfg] = useState(() => {
    try {
      const saved = JSON.parse(localStorage.getItem("seavin.cfg") || "null");
      if (saved) return { ...defaults, ...saved };
    } catch (e) {}
    return defaults;
  });
  useApplyConfig(cfg);
  return [cfg, setCfg];
}

/* ============================================
   Shared: page wrapper
   ============================================ */
function Page({ active, children, cfg, setCfg, t, minimal = false }) {
  return (
    <div className="page">
      <Nav
        active={active}
        minimal={minimal}
        t={t}
        lang={cfg.lang}
        onLang={(v) => {
          const next = { ...cfg, lang: v };
          setCfg(next);
          try { localStorage.setItem("seavin.cfg", JSON.stringify(next)); } catch(e) {}
        }}
      />
      <main className="page__main">{children}</main>
      <Footer t={t} lang={cfg.lang} />
      <TweaksPanel cfg={cfg} setCfg={setCfg} />
    </div>
  );
}

/* ============================================
   Section Head
   ============================================ */
function SectionHead({ num, kicker, titlePlain, titleItalic, center = false }) {
  if (center) {
    return (
      <div className="section-head section-head--center">
        <div className="section-head__num">{num}</div>
        <div className="eyebrow" style={{ marginTop: 10 }}>{kicker}</div>
        <h2>
          {titlePlain}{" "}
          <em>{titleItalic}</em>
        </h2>
      </div>
    );
  }
  return (
    <div className="section-head">
      <div>
        <div className="section-head__num">{num}</div>
        <div className="eyebrow" style={{ marginTop: 12 }}>{kicker}</div>
      </div>
      <h2>
        {titlePlain}{" "}
        <em>{titleItalic}</em>
      </h2>
    </div>
  );
}

/* ============================================
   Stamp
   ============================================ */
function Stamp({ children, style }) {
  return <span className="stamp" style={style}>{children}</span>;
}

/* ============================================
   Request tracker state (shared via localStorage)
   ============================================ */
const SEAVIN_REQ_KEY = "seavin.request";
function loadRequest() {
  try { return JSON.parse(localStorage.getItem(SEAVIN_REQ_KEY) || "null"); } catch(e) { return null; }
}
function saveRequest(r) {
  try { localStorage.setItem(SEAVIN_REQ_KEY, JSON.stringify(r)); } catch(e) {}
}
function clearRequest() {
  try { localStorage.removeItem(SEAVIN_REQ_KEY); } catch(e) {}
}

/* ============================================
   Photo cropper — circular avatar editor
   "Ghiera" zoom + drag-to-pan + wheel zoom
   Used by surveyor signup and dashboard listing editor.
   ============================================ */
function PhotoCropper({ imageSrc, onConfirm, onCancel, size = 320, outputSize = 512, lang = "it" }) {
  const it = lang === "it";
  const stageRef = useRef(null);
  const [imgEl, setImgEl] = useState(null);     // HTMLImageElement (loaded)
  const [scale, setScale] = useState(1);        // current scale
  const [minScale, setMinScale] = useState(1);  // smallest scale to still cover circle
  const [pos, setPos] = useState({ x: 0, y: 0 });
  const [drag, setDrag] = useState(null);       // {startX, startY, baseX, baseY}

  /* Load the image and compute the minimum scale that still covers the crop circle */
  useEffect(() => {
    const img = new Image();
    img.onload = () => {
      const min = Math.max(size / img.naturalWidth, size / img.naturalHeight);
      setImgEl(img);
      setMinScale(min);
      setScale(min);
      setPos({ x: 0, y: 0 });
    };
    img.onerror = () => onCancel?.();
    img.src = imageSrc;
  }, [imageSrc, size]);

  /* Constrain pan so the image always covers the crop area */
  const clamp = useCallback((p, s = scale) => {
    if (!imgEl) return p;
    const w = imgEl.naturalWidth * s;
    const h = imgEl.naturalHeight * s;
    const maxX = Math.max(0, (w - size) / 2);
    const maxY = Math.max(0, (h - size) / 2);
    return {
      x: Math.min(maxX, Math.max(-maxX, p.x)),
      y: Math.min(maxY, Math.max(-maxY, p.y)),
    };
  }, [imgEl, scale, size]);

  /* Re-clamp when scale changes (zoom out can push image into the void) */
  useEffect(() => { setPos(p => clamp(p)); }, [scale, clamp]);

  /* ---- Drag (mouse + touch) ---- */
  const onPointerDown = (e) => {
    e.preventDefault();
    const pt = "touches" in e ? e.touches[0] : e;
    setDrag({ startX: pt.clientX, startY: pt.clientY, baseX: pos.x, baseY: pos.y });
  };
  useEffect(() => {
    if (!drag) return;
    const move = (e) => {
      const pt = "touches" in e ? e.touches[0] : e;
      setPos(clamp({
        x: drag.baseX + (pt.clientX - drag.startX),
        y: drag.baseY + (pt.clientY - drag.startY),
      }));
    };
    const up = () => setDrag(null);
    window.addEventListener("mousemove", move);
    window.addEventListener("mouseup", up);
    window.addEventListener("touchmove", move, { passive: false });
    window.addEventListener("touchend", up);
    return () => {
      window.removeEventListener("mousemove", move);
      window.removeEventListener("mouseup", up);
      window.removeEventListener("touchmove", move);
      window.removeEventListener("touchend", up);
    };
  }, [drag, clamp]);

  /* ---- Wheel zoom on stage ---- */
  useEffect(() => {
    const stage = stageRef.current;
    if (!stage) return;
    const onWheel = (e) => {
      e.preventDefault();
      const factor = e.deltaY < 0 ? 1.06 : 1 / 1.06;
      setScale(s => Math.min(minScale * 4, Math.max(minScale, s * factor)));
    };
    stage.addEventListener("wheel", onWheel, { passive: false });
    return () => stage.removeEventListener("wheel", onWheel);
  }, [minScale]);

  /* ---- Confirm: paint to canvas, return JPEG data URL ---- */
  const confirm = () => {
    if (!imgEl) return;
    const canvas = document.createElement("canvas");
    canvas.width = outputSize;
    canvas.height = outputSize;
    const ctx = canvas.getContext("2d");
    /* Circular clip */
    ctx.save();
    ctx.beginPath();
    ctx.arc(outputSize / 2, outputSize / 2, outputSize / 2, 0, Math.PI * 2);
    ctx.closePath();
    ctx.clip();
    /* Translate the on-screen composition into output-space coordinates */
    const ratio = outputSize / size;
    const w = imgEl.naturalWidth * scale * ratio;
    const h = imgEl.naturalHeight * scale * ratio;
    const x = (outputSize - w) / 2 + pos.x * ratio;
    const y = (outputSize - h) / 2 + pos.y * ratio;
    ctx.drawImage(imgEl, x, y, w, h);
    ctx.restore();
    onConfirm(canvas.toDataURL("image/jpeg", 0.86));
  };

  const zoomPct = minScale > 0 ? Math.round((scale / minScale) * 100) : 100;

  return (
    <div className="cropper-backdrop" onClick={onCancel}>
      <div className="cropper" onClick={(e) => e.stopPropagation()} role="dialog" aria-label={it ? "Adatta foto profilo" : "Adjust profile photo"}>
        <div className="cropper__head">
          <span className="mono" style={{ fontSize: 11, letterSpacing: "0.18em", color: "var(--ink-mute)" }}>§ {it ? "ADATTA FOTO" : "ADJUST PHOTO"}</span>
          <button className="modal__close" onClick={onCancel} aria-label="Close">×</button>
        </div>
        <h3 className="cropper__h">
          {it ? "Posiziona il" : "Position the"} <em style={{ fontStyle: "italic", color: "var(--accent-deep)" }}>{it ? "tuo viso" : "subject"}</em>
        </h3>
        <p className="cropper__sub">
          {it ? "Trascina per spostare · ruota la ghiera o usa la rotella per ingrandire." : "Drag to move · turn the dial or scroll to zoom."}
        </p>

        <div
          ref={stageRef}
          className="cropper__stage"
          style={{ width: size, height: size }}
          onMouseDown={onPointerDown}
          onTouchStart={onPointerDown}
        >
          {imgEl && (
            <img
              src={imageSrc}
              alt=""
              draggable={false}
              className="cropper__img"
              style={{
                width: imgEl.naturalWidth * scale,
                height: imgEl.naturalHeight * scale,
                transform: `translate(calc(-50% + ${pos.x}px), calc(-50% + ${pos.y}px))`,
              }}
            />
          )}
          <div className="cropper__mask" aria-hidden="true"/>
        </div>

        <div className="cropper__dial">
          <button
            type="button"
            className="cropper__dial-btn"
            onClick={() => setScale(s => Math.max(minScale, s / 1.12))}
            aria-label={it ? "Riduci" : "Zoom out"}
          >−</button>
          <div className="cropper__dial-track">
            <input
              type="range"
              min={minScale}
              max={minScale * 4}
              step={0.001}
              value={scale}
              onChange={(e) => setScale(Number(e.target.value))}
              aria-label={it ? "Zoom" : "Zoom"}
              className="cropper__dial-input"
            />
            <span className="mono cropper__dial-pct">{zoomPct}%</span>
          </div>
          <button
            type="button"
            className="cropper__dial-btn"
            onClick={() => setScale(s => Math.min(minScale * 4, s * 1.12))}
            aria-label={it ? "Ingrandisci" : "Zoom in"}
          >+</button>
        </div>

        <div className="cropper__actions">
          <button type="button" className="btn btn--ghost" onClick={onCancel}>{it ? "Annulla" : "Cancel"}</button>
          <button type="button" className="btn btn--accent" onClick={confirm}>{it ? "Applica ritaglio" : "Apply crop"}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  Logo, Nav, Footer, TweaksPanel, Page, SectionHead, Stamp, PhotoCropper,
  useConfig, useApplyConfig,
  loadRequest, saveRequest, clearRequest,
});
