// curators.jsx — Ryoko · curator (Voyage Architect) registry + reusable card
// Exposes:
//   window.RyokoCurators       — keyed by id (co, tn, ts, hm, yt, dv, rd)
//   window.RyokoCuratorCard    — <RyokoCuratorCard id="co" note="..." size="default|compact|inline|trace" />
//   window.RyokoCuratorByline  — <RyokoCuratorByline id="co" verb="held" /> · short attribution line
//
// The handwritten note uses the Caveat font (loaded by curators.css).
// This registry is the sole source of architect data — atelier/data.jsx,
// which it used to mirror, was retired in the final folder cull.

(function () {
  const { useState, useEffect } = React;

  // Subscribe to discreet (off-book) state so curator attribution can be
  // suppressed when a member is browsing without their architect watching.
  function useDiscreet() {
    const [on, setOn] = useState(
      typeof window !== "undefined" && window.RyokoDiscreet ? window.RyokoDiscreet.isOn() : false
    );
    useEffect(() => {
      if (!window.RyokoDiscreet) return;
      const unsub = window.RyokoDiscreet.subscribe(setOn);
      setOn(window.RyokoDiscreet.isOn());
      return unsub;
    }, []);
    return on;
  }

  // Anonymous attribution shown in place of an architect when off-book.
  // The whole point of off-book: you're not looking with your architect.
  const HOUSE = {
    id: "house",
    name: "The House",
    shortName: "the House",
    title: "Off-book · architect not watching",
    avatar: "·",
    portrait: null,
    since: "anonymous session",
    contact: { line: "—", mail: "—" },
    signature: "the House",
    otherWorkHref: "#",
  };

  const ARCHITECTS = {
    co: {
      id: "co",
      name: "Camille Okafor",
      shortName: "Camille",
      title: "Lead Architect, London",
      avatar: "CO",
      portrait: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2021",
      contact: { line: "+44 20 4525 1100", mail: "camille@ryoko.travel" },
      relationships: 142,
      yearsAtHouse: 8,
      signature: "Camille",
      otherWorkHref: "../landing/Landing.html",
    },
    tn: {
      id: "tn",
      name: "Takumi Nakamura",
      shortName: "Takumi",
      title: "Architect — Japan & East Asia",
      avatar: "TN",
      portrait: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2023",
      contact: { line: "+81 75 213 4400", mail: "takumi@ryoko.travel" },
      relationships: 64,
      yearsAtHouse: 3,
      signature: "Takumi",
      otherWorkHref: "../landing/Landing.html",
    },
    ts: {
      id: "ts",
      name: "Themba Sithole",
      shortName: "Themba",
      title: "Architect — Africa & the Indian Ocean",
      avatar: "TS",
      portrait: "https://images.unsplash.com/photo-1552058544-f2b08422138a?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2024",
      contact: { line: "+27 11 234 0900", mail: "themba@ryoko.travel" },
      relationships: 81,
      yearsAtHouse: 6,
      signature: "Themba",
      otherWorkHref: "../landing/Landing.html",
    },
    hm: {
      id: "hm",
      name: "Hélène Marchand",
      shortName: "Hélène",
      title: "Architect — France, Switzerland & Monaco",
      avatar: "HM",
      portrait: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2024",
      contact: { line: "+33 1 44 71 15 00", mail: "helene@ryoko.travel" },
      relationships: 96,
      yearsAtHouse: 4,
      signature: "Hélène",
      otherWorkHref: "../landing/Landing.html",
    },
    yt: {
      id: "yt",
      name: "Yuki Tanaka",
      shortName: "Yuki",
      title: "Architect — Hokkaidō & winter mountain",
      avatar: "YT",
      portrait: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&q=85&fit=crop&crop=faces",
      since: "Niseko office",
      contact: { line: "+81 136 21 8200", mail: "yuki@ryoko.travel" },
      relationships: 38,
      yearsAtHouse: 2,
      signature: "Yuki",
      otherWorkHref: "../landing/Landing.html",
    },
    dv: {
      id: "dv",
      name: "Diego Velasco",
      shortName: "Diego",
      title: "Architect — the Americas",
      avatar: "DV",
      portrait: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2024",
      contact: { line: "+1 212 555 4400", mail: "diego@ryoko.travel" },
      relationships: 71,
      yearsAtHouse: 3,
      signature: "Diego",
      otherWorkHref: "../landing/Landing.html",
    },
    rd: {
      id: "rd",
      name: "Rohan Desai",
      shortName: "Rohan",
      title: "Architect — South Asia & the Subcontinent",
      avatar: "RD",
      portrait: "https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=400&q=85&fit=crop&crop=faces",
      since: "with you since 2024",
      contact: { line: "+44 20 4525 1112", mail: "rohan@ryoko.travel" },
      relationships: 52,
      yearsAtHouse: 2,
      signature: "Rohan",
      otherWorkHref: "../landing/Landing.html",
    },
  };

  // Resolve relative path back to root from the current page (mirrors topbar logic).
  function rootPrefix() {
    try {
      const path = window.location.pathname;
      const parts = path.split("/").filter(Boolean);
      const dirs = parts.slice(0, -1);
      const depth = dirs.length;
      if (depth <= 0) return "./";
      return "../".repeat(depth);
    } catch (e) { return "../"; }
  }

  // Resolve an architect by id. Accepts also { id, note } shape.
  function resolve(input) {
    if (!input) return null;
    const id = typeof input === "string" ? input : (input.id || input.curatorId);
    return ARCHITECTS[id] || null;
  }

  // ── Card variants ─────────────────────────────────────────────────────────
  // size:
  //   "default" — full card, portrait + handwritten note + verifier strip
  //   "compact" — smaller, no handwritten note (eyebrow attribution)
  //   "trace"   — wide stripe for the top of the why-trace modal
  //   "inline"  — single line: face + name only

  function CuratorCard({ id, curator, note, since, size, verb, hand, className, onClick, ariaLabel }) {
    const discreet = useDiscreet();
    const realArchitect = curator || resolve(id);
    if (!realArchitect) return null;
    // Off-book: suppress architect attribution and show anonymous house byline.
    // This is the trust contract — when a principal browses off-book, the
    // architect is not paged and not visibly attached to the activity.
    const a = discreet ? HOUSE : realArchitect;
    const prefix = rootPrefix();
    // otherWorkHref in the registry is relative-to-page-one-deep (uses ../landing/…).
    // Re-resolve from current page depth to keep links honest.
    const otherWork = a.otherWorkHref && a.otherWorkHref.startsWith("../")
      ? a.otherWorkHref.replace(/^\.\.\//, prefix)
      : a.otherWorkHref;
    const handwritten = discreet
      ? null
      : (hand || note);
    const cls = `rk-curator rk-curator-${size || "default"} ${discreet ? "rk-curator-anon" : ""} ${className || ""}`.trim();
    const sinceLine = since || a.since;

    if (size === "inline") {
      const inlineVerb = verb === "" ? null : (verb || "Held by");
      return (
        <span className={cls} aria-label={ariaLabel || `${inlineVerb || "Curator"}: ${a.name}`}>
          <Face a={a} sizeClass="rk-curator-face-tiny" />
          <span className="rk-curator-inline-text">
            {inlineVerb && <>{inlineVerb} </>}<b>{a.shortName}</b>
          </span>
        </span>
      );
    }

    if (size === "compact") {
      return (
        <div className={cls} data-screen-label={`Curator · ${a.name}`}>
          <FaceLink a={a} sizeClass="rk-curator-face-sm" otherWork={otherWork} />
          <div className="rk-curator-meta">
            <div className="rk-curator-eyebrow">{discreet ? "Off-book · architect not watching" : (verb || "Held in your name by")}</div>
            <div className="rk-curator-name">
              {discreet
                ? "The House · anonymised"
                : <>{a.shortName} <span className="rk-curator-surname">{a.name.replace(a.shortName, "").trim()}</span></>}
            </div>
            <div className="rk-curator-since">{sinceLine}</div>
          </div>
        </div>
      );
    }

    if (size === "trace") {
      return (
        <div className={cls} data-screen-label={`Curator note · ${a.name}`}>
          <FaceLink a={a} sizeClass="rk-curator-face-md" otherWork={otherWork} ring />
          <div className="rk-curator-meta">
            <div className="rk-curator-eyebrow">
              {discreet
                ? "Off-book · attribution suppressed"
                : <>A note from {a.shortName} · {verb || "your architect"}</>}
            </div>
            {handwritten && (
              <div className="rk-curator-hand rk-curator-hand-trace">
                <span className="rk-curator-hand-text">"{handwritten}"</span>
                <span className="rk-curator-hand-sig">— {a.signature}</span>
              </div>
            )}
            {discreet && (
              <div className="rk-curator-anon-note">
                Your architect has not been paged for this trace · these signals are computed locally and not added to your file.
              </div>
            )}
            <div className="rk-curator-foot">
              <span className="rk-curator-name">{a.name}</span>
              <span className="rk-curator-sep">·</span>
              <span className="rk-curator-title">{a.title}</span>
              {!discreet && otherWork && otherWork !== "#" && (
                <a className="rk-curator-link" href={otherWork}>Their other work →</a>
              )}
            </div>
          </div>
        </div>
      );
    }

    // default
    return (
      <div className={cls} data-screen-label={`Curator card · ${a.name}`} onClick={onClick}>
        <div className="rk-curator-paper" aria-hidden />
        <FaceLink a={a} sizeClass="rk-curator-face-md" otherWork={otherWork} ring />
        <div className="rk-curator-meta">
          <div className="rk-curator-eyebrow">{discreet ? "Off-book · architect not watching" : (verb || "Held in your name by")}</div>
          <div className="rk-curator-name">{discreet ? "The House" : a.name}</div>
          <div className="rk-curator-title">{a.title}</div>
          {handwritten && (
            <div className="rk-curator-hand">
              <span className="rk-curator-hand-text">"{handwritten}"</span>
              <span className="rk-curator-hand-sig">— {a.signature}</span>
            </div>
          )}
          {discreet && (
            <div className="rk-curator-anon-note">
              Architect attribution is suppressed during off-book sessions. Saves and views here are not added to your file.
            </div>
          )}
          <div className="rk-curator-foot">
            <span className="rk-curator-since">{sinceLine}</span>
            {!discreet && (
              <>
                <span className="rk-curator-sep">·</span>
                <a className="rk-curator-link" href={`mailto:${a.contact.mail}`}>Send a note in confidence →</a>
              </>
            )}
          </div>
        </div>
      </div>
    );
  }

  // ── Face / FaceLink helpers · render a portrait OR an off-book monogram ──
  function Face({ a, sizeClass }) {
    if (a.portrait) {
      return (
        <span className={`rk-curator-face ${sizeClass}`} aria-hidden>
          <img src={a.portrait} alt="" loading="lazy" />
        </span>
      );
    }
    return (
      <span className={`rk-curator-face ${sizeClass} rk-curator-face-anon`} aria-hidden>
        <svg width="60%" height="60%" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
          <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" />
        </svg>
      </span>
    );
  }
  function FaceLink({ a, sizeClass, otherWork, ring }) {
    const ringEl = ring ? <span className="rk-curator-face-ring" aria-hidden /> : null;
    if (!otherWork || otherWork === "#") {
      return (
        <span className={`rk-curator-face ${sizeClass} ${a.portrait ? "" : "rk-curator-face-anon"}`} aria-hidden>
          {a.portrait ? <img src={a.portrait} alt="" loading="lazy" /> : (
            <svg width="60%" height="60%" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" />
            </svg>
          )}
          {ringEl}
        </span>
      );
    }
    return (
      <a className={`rk-curator-face ${sizeClass} ${a.portrait ? "" : "rk-curator-face-anon"}`} href={otherWork} aria-label={`See ${a.shortName}'s other work`}>
        {a.portrait
          ? <img src={a.portrait} alt={`Portrait of ${a.name}`} loading="lazy" />
          : (
            <svg width="60%" height="60%" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" />
            </svg>
          )}
        {ringEl}
      </a>
    );
  }

  function CuratorByline({ id, curator, verb, className }) {
    return <CuratorCard id={id} curator={curator} verb={verb || "Held by"} size="inline" className={className} />;
  }

  window.RyokoCurators = ARCHITECTS;
  window.RyokoCuratorResolve = resolve;
  window.RyokoCuratorCard = CuratorCard;
  window.RyokoCuratorByline = CuratorByline;
})();
