// Editorial Agency Profile.
// Full-width ledger → contained 4:5 hero → stats sheet → centred bio →
// justified portfolio gallery (click to enlarge, video plays) → footer.

function ProfileClinical({ model, tweaks }) {
  const rootRef = React.useRef(null);
  React.useEffect(() => { applyTheme(rootRef.current, tweaks); }, [tweaks]);

  const { hero, gallery, statsDensity, mediaCount } = tweaks;
  const media     = model.media.slice(0, mediaCount);
  const heroItem  = media[0];
  const rest      = media.slice(1);
  const stats     = statsDensity === "minimal"
    ? model.stats.filter((s) =>
        ["Age", "Height", "Cup size", "Dress", "Shoe", "Hair", "Eyes",
         "Based in", "Availability", "Travel"]
          .includes(s.k))
    : model.stats;

  // ── Lightbox state — keyed off the FULL media list (incl. hero) so
  // clicking the hero also opens it as item 0. ──
  const lb = useLightbox(media);

  return (
    <div ref={rootRef} style={{
      width:"100%", minHeight:"100%",
      fontFamily:"var(--font-body)",
      "--col-pad":"clamp(28px, 4vw, 64px)",
      "--max-w":"1480px",
      "--mono":'"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace',
    }}>
      <ClHeaderLedger model={model}/>

      {hero === "masthead" ? (
        <ClHeroMasthead model={model} item={heroItem} onOpen={() => lb.open(0)}/>
      ) : hero === "split" ? (
        <ClHeroSplit    model={model} item={heroItem} stats={stats} onOpen={() => lb.open(0)}/>
      ) : (
        <ClHeroOverlay  model={model} item={heroItem} onOpen={() => lb.open(0)}/>
      )}

      <ClStatsSheet stats={stats}/>
      <ClBio model={model}/>
      <ClPersonality model={model}/>
      <ClGallery
        items={rest}
        layout={gallery}
        onOpen={(restIdx) => lb.open(restIdx + 1)}
      />
      <ClFooter model={model}/>

      <Lightbox
        items={media}
        idx={lb.idx}
        onClose={lb.close}
        onPrev={lb.prev}
        onNext={lb.next}
      />
    </div>
  );
}

// ─── Top ledger ────────────────────────────────────────────────────────
function ClHeaderLedger({ model }) {
  return (
    <div style={{
      display:"grid", gridTemplateColumns:"1.2fr 1fr 1fr",
      borderBottom:"1px solid var(--rule-strong)",
      fontFamily:"var(--mono)",
      fontSize: 10.5, letterSpacing:".14em", textTransform:"uppercase",
    }}>
      <ClLedgerCell>
        <ClLK>Talent</ClLK>
        <ClLV>{model.firstName} {model.lastName}</ClLV>
      </ClLedgerCell>
      <ClLedgerCell>
        <ClLK>Index</ClLK>
        <ClLV>042 / 300</ClLV>
      </ClLedgerCell>
      <ClLedgerCell right>
        <ClLK>File</ClLK>
        <ClLV>EV-42 · R 26.05</ClLV>
      </ClLedgerCell>
    </div>
  );
}
function ClLedgerCell({ children, right }) {
  return (
    <div style={{
      padding:"16px clamp(20px, 2.5vw, 32px)",
      borderLeft:"1px solid var(--rule)",
      display:"flex", alignItems:"center", gap: 12,
      justifyContent: right ? "flex-end" : "flex-start",
    }}>{children}</div>
  );
}
function ClLK({ children }) { return <span style={{ color:"var(--fg-faint)" }}>{children}</span>; }
function ClLV({ children }) { return <span style={{ color:"var(--fg)", fontWeight:500 }}>{children}</span>; }

// ─── Hero: contained 4:5 portrait, name overlay (DEFAULT) ──────────────
//
// The frame is height-bounded so the hero doesn't dominate the page —
// it caps at ~84vh on tall screens, sits centred with bone-coloured
// margins on the sides. Aspect stays 4:5 at all sizes.
function ClHeroOverlay({ model, item, onOpen }) {
  // Pull a handful of vitals from the stats array so the bottom strip
  // shows real values from the registration form (no labels — the values
  // alone read as model vitals in context).
  const valueOf = (k) => model.stats.find((s) => s.k === k)?.v;
  const age     = valueOf("Age");
  const basedIn = valueOf("Based in");
  const height  = valueOf("Height");
  return (
    <section style={{
      padding:"clamp(28px, 4vw, 56px) var(--col-pad)",
      display:"flex", justifyContent:"center",
    }}>
      <div style={{ width:"100%", maxWidth:"min(960px, 100%)" }}>
        <div
          onClick={onOpen}
          role="button"
          tabIndex={0}
          style={{
            position:"relative",
            width:"100%",
            aspectRatio:"4 / 5",
            maxHeight:"calc(100vh - 140px)",
            margin:"0 auto",
            overflow:"hidden",
            background:"#1a1816",
            cursor:"zoom-in",
          }}
        >
          {/* Aspect-ratio + max-height conflict resolution: when max-height
              clamps, width naturally narrows because aspectRatio still binds. */}
          <MediaItem item={item} crop={true} style={{ width:"100%", height:"100%" }}/>

          {/* Subtle bottom vignette so name + meta stay legible */}
          <div style={{
            position:"absolute", inset:0,
            background:
              "linear-gradient(180deg, rgba(0,0,0,0.16) 0%, rgba(0,0,0,0) 22%, " +
              "rgba(0,0,0,0) 48%, rgba(0,0,0,0.5) 100%)",
            pointerEvents:"none",
          }}/>

          {/* Name — lower-centre */}
          <div style={{
            position:"absolute", top:"56%", left:0, right:0,
            display:"flex", flexDirection:"column", alignItems:"center",
            color:"#f6f0e2", textAlign:"center",
            padding:"0 8%", pointerEvents:"none",
          }}>
            <div style={{
              fontFamily:"var(--font-display)",
              fontWeight:"var(--display-weight)",
              letterSpacing:"var(--name-tracking)",
              lineHeight:"var(--display-leading)",
              fontSize:"clamp(64px, 9vw, 156px)",
              textShadow:"0 2px 28px rgba(0,0,0,0.28)",
            }}>
              <div>{model.firstName.toUpperCase()}</div>
              <div style={{ marginTop:"-0.08em" }}>{model.lastName.toUpperCase()}</div>
            </div>
          </div>

          {/* Bottom vitals strip — age · based in · height */}
          <div style={{
            position:"absolute", bottom:0, left:0, right:0,
            padding:"22px 6%",
            display:"flex", justifyContent:"space-between", alignItems:"center",
            color:"rgba(246,240,226,0.92)",
            fontFamily:"var(--mono)",
            fontSize: "clamp(11px, 0.95vw, 14px)",
            letterSpacing:".18em", textTransform:"uppercase",
            pointerEvents:"none",
          }}>
            <span>{age}</span>
            <span>{basedIn}</span>
            <span>{height}</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─── Hero: Masthead (name big above contained image) ───────────────────
function ClHeroMasthead({ model, item, onOpen }) {
  return (
    <section style={{ padding:"clamp(48px, 6vw, 80px) var(--col-pad) 0" }}>
      <div style={{
        maxWidth:"var(--max-w)", margin:"0 auto",
        fontFamily:"var(--font-display)",
        fontWeight:"var(--display-weight)",
        letterSpacing:"var(--name-tracking)",
        lineHeight:"var(--display-leading)",
        fontSize:"clamp(96px, 14vw, 220px)",
        textAlign:"center",
      }}>
        <div>{model.firstName.toUpperCase()}</div>
        <div>{model.lastName.toUpperCase()}</div>
      </div>
      <div style={{
        maxWidth:"min(880px, 100%)", margin:"40px auto",
      }}>
        <div onClick={onOpen} style={{
          aspectRatio:"4 / 5", maxHeight:"calc(100vh - 200px)",
          margin:"0 auto", overflow:"hidden", background:"#1a1816",
          cursor:"zoom-in",
        }}>
          <MediaItem item={item} crop={true} style={{ width:"100%", height:"100%" }}/>
        </div>
      </div>
    </section>
  );
}

// ─── Hero: Split ───────────────────────────────────────────────────────
function ClHeroSplit({ model, item, stats, onOpen }) {
  return (
    <section style={{
      display:"grid", gridTemplateColumns:"1fr 1fr",
      borderBottom:"1px solid var(--rule-strong)",
      minHeight:"min(820px, 84vh)",
    }}>
      <div style={{
        padding:"clamp(36px, 5vw, 64px) var(--col-pad)",
        display:"flex", flexDirection:"column", justifyContent:"space-between",
        borderRight:"1px solid var(--rule)",
      }}>
        <div>
          <div style={{
            fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
            textTransform:"uppercase", color:"var(--fg-faint)", marginBottom: 22,
          }}>
            File R-26.05 · 042 · {model.city}
          </div>
          <div style={{
            fontFamily:"var(--font-display)",
            fontWeight:"var(--display-weight)",
            letterSpacing:"var(--name-tracking)",
            lineHeight: 0.88,
            fontSize:"clamp(72px, 8vw, 140px)",
          }}>
            <div>{model.firstName.toUpperCase()}</div>
            <div>{model.lastName.toUpperCase()}</div>
          </div>
        </div>
        <div style={{
          marginTop: 60,
          fontFamily:"var(--mono)", fontSize:11, lineHeight:1.95, letterSpacing:".04em",
          textTransform:"uppercase",
          borderTop:"1px solid var(--rule)", paddingTop:18,
          maxWidth: 460,
        }}>
          {stats.slice(0, 8).map((s) => (
            <div key={s.k} style={{ display:"flex", justifyContent:"space-between", gap:24 }}>
              <span style={{color:"var(--fg-faint)"}}>{s.k}</span>
              <span style={{color:"var(--fg)"}}>{s.v}</span>
            </div>
          ))}
        </div>
      </div>
      <div onClick={onOpen} style={{ height:"100%", overflow:"hidden", cursor:"zoom-in" }}>
        <MediaItem item={item} crop={true} style={{ height:"100%" }}/>
      </div>
    </section>
  );
}

// ─── Stats sheet ───────────────────────────────────────────────────────
function ClStatsSheet({ stats }) {
  return (
    <section style={{
      padding:"clamp(56px, 6vw, 88px) var(--col-pad)",
      maxWidth:"var(--max-w)", margin:"0 auto",
      width:"100%",
    }}>
      <ClSectionHead num="01" label="Statistics" right="Submitted data"/>
      <div style={{
        marginTop: 32,
        display:"grid", gridTemplateColumns:"1fr 1fr",
        columnGap:"clamp(40px, 5vw, 80px)",
      }}>
        {[stats.slice(0, Math.ceil(stats.length / 2)),
          stats.slice(Math.ceil(stats.length / 2))].map((col, ci) => (
          <div key={ci}>
            {col.map((s) => <ClStatRow key={s.k} k={s.k} v={s.v} sub={s.sub}/>)}
          </div>
        ))}
      </div>
    </section>
  );
}
function ClStatRow({ k, v, sub }) {
  return (
    <div style={{
      display:"grid", gridTemplateColumns:"150px 1fr auto",
      alignItems:"baseline",
      padding:"18px 0",
      borderBottom:"1px solid var(--rule)",
      fontFamily:"var(--mono)",
      fontSize:12, letterSpacing:".04em", textTransform:"uppercase",
      columnGap: 18,
    }}>
      <span style={{ color:"var(--fg-faint)" }}>{k}</span>
      <span style={{ color:"var(--fg)", fontWeight:500 }}>{v}</span>
      <span style={{ color:"var(--fg-soft)", fontSize:11 }}>{sub || ""}</span>
    </div>
  );
}

// ─── Section head ──────────────────────────────────────────────────────
function ClSectionHead({ num, label, right }) {
  return (
    <div style={{
      display:"flex", alignItems:"baseline", justifyContent:"space-between",
      borderTop:"1px solid var(--rule-strong)", paddingTop: 20, gap: 24,
    }}>
      <div style={{ display:"flex", alignItems:"baseline", gap: 18 }}>
        <span style={{
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
          color:"var(--fg-faint)", textTransform:"uppercase",
        }}>— {num}</span>
        <span style={{
          fontFamily:"var(--font-display)", fontWeight:"var(--display-weight)",
          fontSize:"clamp(28px, 3vw, 40px)", letterSpacing:"-0.02em", lineHeight:1,
        }}>{label}</span>
      </div>
      {right && (
        <span style={{
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
          color:"var(--fg-faint)", textTransform:"uppercase", textAlign:"right",
        }}>{right}</span>
      )}
    </div>
  );
}

// ─── Bio ──────────────────────────────────────────────────────────────
function ClBio({ model }) {
  return (
    <section style={{
      padding:"clamp(40px, 5vw, 72px) var(--col-pad) clamp(56px, 6vw, 96px)",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <ClSectionHead num="02" label="Biography"/>
      <div style={{
        marginTop: 56,
        maxWidth: 760, marginInline:"auto",
        fontFamily:"var(--font-display)",
        fontSize:"clamp(22px, 2.2vw, 30px)",
        lineHeight: 1.4,
        letterSpacing:"-0.005em",
        textWrap:"pretty",
        textAlign:"center",
        color:"var(--fg)",
      }}>
        {model.bio}
      </div>
      <div style={{
        marginTop: 28, textAlign:"center",
        fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".22em",
        textTransform:"uppercase", color:"var(--fg-faint)",
      }}>
        — {model.firstName} {model.lastName}
      </div>
    </section>
  );
}

// ─── Personality (free text from registration form) ────────────────────
// Visually distinct from Bio: italic, narrower column, smaller scale —
// reads as a personal note rather than the professional artist statement.
function ClPersonality({ model }) {
  if (!model.personality) return null;
  return (
    <section style={{
      padding:"0 var(--col-pad) clamp(56px, 6vw, 96px)",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <ClSectionHead num="03" label="Personality" right="In her own words"/>
      <div style={{
        marginTop: 48,
        maxWidth: 620, marginInline:"auto",
        fontFamily:"var(--font-display)",
        fontStyle:"italic",
        fontSize:"clamp(18px, 1.7vw, 24px)",
        lineHeight: 1.55,
        letterSpacing:"-0.005em",
        textWrap:"pretty",
        textAlign:"center",
        color:"var(--fg-soft)",
      }}>
        “{model.personality}”
      </div>
    </section>
  );
}

// ─── Gallery ───────────────────────────────────────────────────────────
function ClGallery({ items, layout, onOpen }) {
  const videoCount = items.filter((it) => it.kind === "video").length;
  const right = videoCount
    ? `${items.length} works · ${videoCount} ${videoCount === 1 ? "film" : "films"}`
    : `${items.length} works`;
  return (
    <section style={{
      padding:"0 var(--col-pad) clamp(56px, 6vw, 96px)",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <ClSectionHead num="04" label="Portfolio" right={right}/>
      <div style={{ marginTop: 36 }}>
        {layout === "grid"      ? <ClGridStrict items={items} onOpen={onOpen}/> :
         layout === "cinematic" ? <ClCinematic items={items} onOpen={onOpen}/>  :
                                  <ClJustified items={items} onOpen={onOpen}/>}
      </div>
    </section>
  );
}

function ClJustified({ items, onOpen }) {
  const ref = React.useRef(null);
  const width = useElementWidth(ref);
  const target = items.length <= 4 ? 620
              :  items.length <= 7 ? 520
              :  items.length <= 11 ? 440 : 380;
  const gap = 8;
  // Tag each item with its index so it survives justifyRows's spread-clones
  // — the lightbox needs the rest-index back when a tile is clicked.
  const tagged = React.useMemo(
    () => items.map((it, idx) => ({ ...it, _idx: idx })),
    [items],
  );
  const rows = width > 0 ? justifyRows(tagged, width, target, gap, 1.4) : [];

  return (
    <div ref={ref} style={{ display:"flex", flexDirection:"column", gap }}>
      {rows.map((row, ri) => (
        <div key={ri} style={{ display:"flex", gap, width:"100%" }}>
          {row.items.map((it) => (
            <GalleryFig
              key={it.i}
              item={it}
              w={it._w} h={it._h}
              onOpen={() => onOpen(it._idx)}
            />
          ))}
        </div>
      ))}
    </div>
  );
}

function ClGridStrict({ items, onOpen }) {
  return (
    <div style={{ display:"grid", gridTemplateColumns:"repeat(3, 1fr)", gap: 8 }}>
      {items.map((it, idx) => (
        <GalleryFig
          key={it.i}
          item={it}
          aspect="3 / 4"
          crop
          onOpen={() => onOpen(idx)}
        />
      ))}
    </div>
  );
}

function ClCinematic({ items, onOpen }) {
  return (
    <div style={{ display:"flex", flexDirection:"column", gap: 12 }}>
      {items.map((it, idx) => (
        <GalleryFig
          key={it.i}
          item={it}
          full
          onOpen={() => onOpen(idx)}
        />
      ))}
    </div>
  );
}

// One figure. Either justified ({w, h}), strict grid (aspect + crop), or
// cinematic (full = full width, natural aspect).
function GalleryFig({ item, w, h, aspect, crop, full, onOpen }) {
  const styleProps = full
    ? { width:"100%" }
    : aspect
      ? { aspectRatio: aspect }
      : { width: w, height: h, flex: `0 0 ${w}px` };

  return (
    <figure
      onClick={onOpen}
      role="button"
      tabIndex={0}
      style={{
        margin:0, position:"relative", overflow:"hidden",
        background:"#1a1816", cursor:"zoom-in",
        ...styleProps,
      }}
    >
      <MediaItem item={item} crop={!!crop} style={{ width:"100%", height: crop || full ? (crop ? "100%" : "auto") : "100%" }}/>
      <ClImageNumber n={item.i}/>
    </figure>
  );
}

// Number-only caption — top-right corner, faint mono pill.
function ClImageNumber({ n }) {
  return (
    <div style={{
      position:"absolute", top:10, right:12,
      color:"rgba(246,240,226,0.86)",
      fontFamily:"var(--mono)",
      fontSize: 10, letterSpacing:".18em", textTransform:"uppercase",
      padding:"3px 8px", borderRadius: 999,
      background:"rgba(10,10,10,0.32)",
      backdropFilter:"blur(4px)",
      WebkitBackdropFilter:"blur(4px)",
      pointerEvents:"none",
    }}>
      {String(n).padStart(2, "0")}
    </div>
  );
}

// ─── Footer — just the credit line ─────────────────────────────────────
function ClFooter({ model }) {
  return (
    <footer style={{
      padding:"clamp(36px, 4vw, 56px) var(--col-pad)",
      background:"var(--bg-deep)",
      borderTop:"1px solid var(--rule-strong)",
    }}>
      <div style={{
        maxWidth:"var(--max-w)", margin:"0 auto",
        display:"flex", justifyContent:"space-between", alignItems:"center",
        fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
        textTransform:"uppercase", color:"var(--fg-faint)",
      }}>
        <span>© {model.agency} 2026</span>
        <span>File R-26.05</span>
        <span>{model.firstName} {model.lastName}</span>
      </div>
    </footer>
  );
}

Object.assign(window, { ProfileClinical });
