const { MicroText, KinoTape, IconStrip, Timecode, Button } = window.DASKINODesignSystem_5a312e;
const { EdRule, EdKicker, EdHead, EdDek, EdBody, EdDropCap, EdCaption, EdSection, EdFolio, EdSpecs } = window;

/* A FICHA como abertura de matéria: o título não fica estampado sobre a foto,
   fica numa página de abertura própria — folio, rubrica, manchete, olho, ficha
   técnica — e a imagem vem DEPOIS, com legenda. É a diferença entre uma capa
   de álbum e uma página de revista, e é o que o v1 não fazia. */
function V2Project({ slug, go }) {
  const i = Math.max(0, window.FILMS.findIndex(f => f.slug === slug));
  const f = window.FILMS[i];
  const next = window.FILMS[(i + 1) % window.FILMS.length];
  const wide = f.motion.filter(m => !m.vertical);
  const tall = f.motion.filter(m => m.vertical);
  const pad = "clamp(20px,4vw,56px)";

  return (
    <div className={"kino-paper " + f.uf} style={{ background: "var(--kino-paper)", color: "var(--text-primary)" }} data-screen-label={"Projeto " + f.word}>

      {/* ABERTURA. A entrega como rúbrica, o título em serif, a linha do
          projeto como olho — e a ficha técnica em mono embaixo. */}
      <section style={{ padding: `clamp(34px,4.4vw,64px) ${pad} 0` }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,300px),1fr))", gap: "clamp(20px,2.8vw,48px)", alignItems: "end", marginBottom: "clamp(24px,3vw,44px)" }}>
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            <EdKicker tone="dim">{f.entrega}</EdKicker>
            <EdHead level="lg" as="h1" weight={450}>{f.title}</EdHead>
            {f.subtitle && <EdHead as="p" level="sm" weight={300} italic style={{ color: "var(--text-secondary)" }}>{f.subtitle}</EdHead>}
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 16, paddingBottom: 4 }}>
            <EdDek measure="narrow">{f.line}</EdDek>
            <EdRule />
            <EdBody size={14.5} dim measure="narrow">{f.sub}</EdBody>
          </div>
        </div>
        <EdSpecs items={[["Entrega", f.entrega], ["Categoria", f.cat], ["Território", f.place], ["Nota", f.nota]]} />
      </section>

      {/* A imagem, limpa. */}
      <section style={{ padding: `clamp(30px,3.6vw,54px) ${pad} 0` }}>
        <div style={{ background: "var(--kino-black)" }}>
          <window.Shot src={f.cover} idx={i} ratio="21:9" overlay={0} />
        </div>
      </section>

      {/* A palavra em fita, preservada do modelo antigo — mas como assinatura
          da matéria, na sua própria linha, e não estampada na foto. */}
      <section style={{ padding: `clamp(26px,3vw,42px) ${pad} 0`, overflow: "hidden" }}>
        <KinoTape ground="light" cap={Math.max(30, Math.min(84, 780 / (0.42 * f.word.length)))} text={f.word} />
      </section>

      {f.motion.length > 0 && (
        <section style={{ padding: `clamp(40px,5vw,72px) ${pad}` }}>
          <EdSection label="MOVIMENTO" count={f.motion.length} />
          {/* 16:9 e 9:16 nunca na mesma grade — alturas de 152 e 480 lado a
              lado deixam meia seção vazia. Duas famílias, duas grades. */}
          <div style={{ display: "flex", flexDirection: "column", gap: "clamp(22px,2.8vw,38px)" }}>
            {wide.length > 0 && (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,280px),1fr))", gap: "clamp(18px,2.2vw,30px)" }}>
                {wide.map((m, n) => <window.MotionPlate key={n} m={m} idx={n} title={f.title} ratio="16:9" />)}
              </div>
            )}
            {tall.length > 0 && (
              <div>
                <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,160px),1fr))", gap: "clamp(16px,2vw,26px)", maxWidth: 800 }}>
                  {tall.map((m, n) => <window.MotionPlate key={n} m={m} idx={n} title={f.title} ratio="9:16" bare />)}
                </div>
              </div>
            )}
          </div>
        </section>
      )}

      {f.signatures.length > 0 && (
        <section style={{ padding: `0 ${pad} clamp(40px,5vw,72px)` }}>
          <EdSection label="ASSINATURAS" count={f.signatures.length} right={<MicroText size="xs" tone="ghost">MARCAS DO CLIENTE</MicroText>} />
          {/* A régua vive em cada peça, não no fundo do contêiner: fundo de
              contêiner em flex-wrap vaza cinza em toda área não preenchida. */}
          <div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
            {f.signatures.map((s, n) => (
              <window.MarkPlate key={n} src={s.src} drive={s.drive} />
            ))}
          </div>
        </section>
      )}

      {/* FOTOGRAFIA. */}
      <section style={{ padding: `0 ${pad} clamp(40px,5vw,72px)` }}>
        <EdSection label={f.photos.length ? "FOTOGRAFIA" : "FRAMES"} count={f.photos.length || f.shots.length}
          right={f.photos.length ? null : <IconStrip items={["globe", "plumb", "diamond"]} size={16} />} />
        {f.photos.length > 0 ? (
          /* A primeira foto ganha largura dupla — uma abertura, não uma fila de
             iguais. É o gesto mais barato que existe para dar hierarquia a uma
             grade, e o que separa uma página composta de um contact sheet. */
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,260px),1fr))", gap: "clamp(18px,2.2vw,30px)" }}>
            {f.photos.map((p, n) => (
              <window.Shot key={n} src={p.src} idx={n} ratio={n === 0 && f.photos.length > 2 ? "16:9" : "4:3"} overlay={0.06}
                style={n === 0 && f.photos.length > 2 ? { gridColumn: "1 / -1" } : undefined} />
            ))}
          </div>
        ) : (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,280px),1fr))", gap: "clamp(18px,2.2vw,30px)" }}>
            {f.shots.map((s, n) => <window.Shot key={n} src={s} idx={n} overlay={0.16} />)}
          </div>
        )}
      </section>

      {/* PRÓXIMO TRABALHO. */}
      <section style={{ padding: `0 ${pad} clamp(48px,6vw,90px)` }}>
        <EdRule weight="double" style={{ marginBottom: "clamp(18px,2.2vw,30px)" }} />
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24, flexWrap: "wrap" }}>
          <Button variant="ghost" onClick={() => go("trabalhos")}>← Arquivo</Button>
          <button onClick={() => go("projeto", next.slug)} style={{ background: "none", border: "none", padding: 0, cursor: "pointer", textAlign: "right", display: "flex", flexDirection: "column", gap: 7, alignItems: "flex-end", color: "var(--text-primary)" }}>
            <MicroText size="xs" tone="ghost">PRÓXIMO</MicroText>
            <EdHead level="sm" weight={450}>{next.title}</EdHead>
          </button>
        </div>
      </section>
    </div>
  );
}

/* PLACA DE MOVIMENTO.
   Os originais do deck têm de 17 a 52 MB. Quatro numa seção são 150 MB, e uma
   página que tenta abrir isso de uma vez simplesmente não abre — foi o que
   deixou a placa da página 24 em branco na primeira montagem.
   Então: o frame parado carrega primeiro (o próprio Drive redimensiona, ~100 KB)
   e a animação só é buscada quando o leitor clica. O peso vai escrito no botão.
   Onde já existe uma versão comprimida — os seis projetos do primeiro lote —
   nada disso é preciso e a peça roda direto. */
function MotionPlate({ m, idx, title, ratio, bare }) {
  const [play, setPlay] = React.useState(!m.heavy);
  const [loading, setLoading] = React.useState(false);
  React.useEffect(() => {
    if (!play || !m.heavy) return;
    setLoading(true);
    const i = new Image();
    i.onload = i.onerror = () => setLoading(false);
    i.src = m.src[m.src.length - 1];
  }, [play]);
  const plate = (
    <div style={{ position: "relative" }}>
      <window.Shot src={play ? m.src : [m.still]} idx={idx} ratio={ratio} overlay={0} />
      {!play && (
        <button onClick={() => setPlay(true)}
          style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,.18)", border: "none", cursor: "pointer", display: "flex", alignItems: "flex-end", justifyContent: "flex-start", padding: 14 }}>
          <span style={{ background: "var(--kino-white)", color: "var(--kino-black)", fontFamily: "var(--font-mono)", fontSize: 9.5, fontWeight: 600, letterSpacing: "0.14em", padding: "6px 10px", display: "flex", gap: 8, alignItems: "center" }}>
            <i style={{ width: 0, height: 0, borderLeft: "6px solid currentColor", borderTop: "4px solid transparent", borderBottom: "4px solid transparent", display: "block" }} />
            MOVIMENTO
          </span>
        </button>
      )}
      {loading && (
        <span style={{ position: "absolute", left: 14, bottom: 14, background: "var(--kino-black)", color: "var(--kino-white)", fontFamily: "var(--font-mono)", fontSize: 9.5, letterSpacing: "0.14em", padding: "6px 10px" }}>CARREGANDO…</span>
      )}
    </div>
  );
  return plate;
}

/* PLACA DE ASSINATURA.
   Dois problemas de uma vez, e os dois vinham de tratar toda marca como igual:

   1. POLARIDADE. As logos embutidas no deck foram desenhadas para slides
      pretos — a maioria é artwork BRANCO sobre transparência. Numa placa branca
      elas desaparecem por completo, e foi o que aconteceu em nove dos onze
      projetos. A placa agora MEDE a imagem: amostra os pixels opacos num canvas
      e escolhe o chão pela luminância do artwork. Marca clara ganha fundo
      escuro, marca escura ganha fundo branco.

      Medir exige CORS, e aí está a sutileza: o servidor das marcas do site v1
      não libera leitura de pixel, o do Drive libera. Então a medição é uma
      TENTATIVA, e o palpite de reserva é CHÃO ESCURO para todas — porque todas
      saem do mesmo lugar, slides pretos de uma apresentação. As marcas do v1
      têm exatamente as mesmas dimensões das do Drive (200×200, 512×512): são o
      mesmo artwork, extraído duas vezes. Tratar as não-mensuráveis como escuras
      seria repetir o erro numa fonte só.

   2. PROPORÇÃO. Um lockup retrato (800×1131) numa caixa de 96 px de altura
      sobra 54 px de logo. As dimensões são legíveis mesmo sem CORS, então a
      caixa cresce sempre que a imagem é mais alta que larga. */
function MarkPlate({ src, drive }) {
  const list = Array.isArray(src) ? src : [src];
  const [n, setN] = React.useState(0);
  const [dead, setDead] = React.useState(false);
  /* Começa assumindo artwork claro — a regra do acervo, não a exceção. */
  const [light, setLight] = React.useState(true);
  const [tall, setTall] = React.useState(false);
  const url = list[n];

  React.useEffect(() => {
    setLight(true);
    /* Passada 1 — dimensões. Funciona em qualquer origem. */
    const plain = new Image();
    plain.referrerPolicy = "no-referrer";
    plain.onload = () => setTall(plain.naturalHeight > plain.naturalWidth * 1.15);
    plain.src = url;
    /* Passada 2 — luminância. Só onde o servidor permite ler os pixels. */
    const probe = new Image();
    probe.crossOrigin = "anonymous";
    probe.referrerPolicy = "no-referrer";
    probe.onload = () => {
      try {
        const s = 40, c = document.createElement("canvas");
        c.width = s; c.height = s;
        const x = c.getContext("2d");
        x.drawImage(probe, 0, 0, s, s);
        const d = x.getImageData(0, 0, s, s).data;
        let sum = 0, count = 0;
        for (let i = 0; i < d.length; i += 4) {
          if (d[i + 3] < 40) continue;          /* ignora transparência */
          sum += 0.299 * d[i] + 0.587 * d[i + 1] + 0.114 * d[i + 2];
          count++;
        }
        if (count) setLight(sum / count > 165);
      } catch (e) { /* CORS fechado: fica o palpite da origem */ }
    };
    probe.src = url;
  }, [url]);

  if (dead) return null;
  return (
    <div style={{ background: light ? "var(--kino-ink)" : "var(--kino-white)", border: "1px solid var(--rule)", height: tall ? 148 : 96, minWidth: 140, display: "flex", alignItems: "center", justifyContent: "center", padding: "18px 26px", boxSizing: "border-box", transition: "background var(--dur-fast) var(--ease-mech)" }}>
      <img src={url} alt="" referrerPolicy="no-referrer"
        onError={() => (n < list.length - 1 ? setN(n + 1) : setDead(true))}
        style={{ maxHeight: "100%", maxWidth: tall ? 130 : 210, objectFit: "contain", display: "block" }} />
    </div>
  );
}

Object.assign(window, { V2Project, MarkPlate, MotionPlate });
