/* Multiligo Social Studio — Layout library
 * Each layout component renders a single slide at native pixel dimensions.
 * Layouts auto-scale to the format's aspect ratio.
 */

const fg = (bg) => bg === 'paper' ? 'var(--ml-ink)' : 'white';
const muted = (bg) => bg === 'paper' ? 'var(--ml-ink-3)' : 'rgba(255,255,255,0.72)';
const line = (bg) => bg === 'paper' ? 'var(--ml-line)' : 'rgba(255,255,255,0.18)';
const accent = (bg) => bg === 'red' ? 'white' : 'var(--ml-red)';

function bgStyle(bg, image, overlayOpacity = 0.5) {
  if (bg === 'overlay') {
    // Gradient baked into overlay PNG — canvas paintGradient step is skipped.
    // Fixes blank text capture: html-to-image struggles with fully-transparent backgrounds.
    return { background: 'linear-gradient(180deg, rgba(0,0,0,0.10) 0%, rgba(0,0,0,0.45) 45%, rgba(0,0,0,0.80) 100%)', color: 'white' };
  }
  if (bg === 'image' && image) {
    const o = overlayOpacity;
    return {
      backgroundImage: `linear-gradient(180deg, rgba(0,0,0,${(o*0.28).toFixed(2)}) 0%, rgba(0,0,0,${Math.min(o*1.1,0.95).toFixed(2)}) 100%), url(${image})`,
      backgroundSize: 'cover', backgroundPosition: 'center',
      color: 'white',
    };
  }
  if (bg === 'ink') return { background: 'var(--ml-ink)', color: 'white' };
  if (bg === 'red') return { background: 'var(--ml-red)', color: 'white' };
  return { background: 'var(--ml-paper)', color: 'var(--ml-ink)' };
}

// Renders an absolutely-positioned full-bleed background video (if slide.video).
// Caller places this as the first child of a relatively-positioned slide root,
// then wraps text content in a div with position: relative + zIndex: 1.
function BgVideo({ video, overlayOpacity = 0.5 }) {
  if (!video || !video.url) return null;
  const o = overlayOpacity;
  const gradient = `linear-gradient(180deg, rgba(0,0,0,${(o*0.1).toFixed(2)}) 0%, rgba(0,0,0,${(o*1.3).toFixed(2)}) 70%, rgba(0,0,0,${Math.min(o*1.7,0.95).toFixed(2)}) 100%)`;
  return (
    <>
      <video
        src={video.url}
        muted autoPlay loop playsInline
        data-bg-overlay="1"
        style={{
          position: 'absolute', inset: 0,
          width: '100%', height: '100%',
          objectFit: 'cover',
          zIndex: 0,
        }}
      />
      <div
        data-bg-overlay="1"
        style={{
          position: 'absolute', inset: 0,
          background: gradient,
          zIndex: 0,
        }}
      />
    </>
  );
}

// When a slide has a video, treat the layout's bg as image (white text + gradient overlay)
// and skip the background-image (the <video> takes over).
function resolveBg(slide) {
  if (slide.video && slide.video.url) return 'image';
  return slide.bg || 'paper';
}

// Uniform scale so layouts fit across square, portrait, story and landscape.
// Baseline: 1080x1080 = 1.0; landscape 1200x627 ≈ 0.58.
function aspectScale(w, h) {
  return Math.min(w, h) / 1080;
}
// rounded scale helper
function S(v, s) { return Math.round(v * s); }

// Safe-zone padding helper. Returns padding style properties.
// When safeZone is active and the format is 9:16 vertical,
// expands top/bottom/right padding to clear Instagram UI chrome.
function szPad(w, h, s, def) {
  const safeZone = (window.__resources || {}).safeZone;
  if (!safeZone || h <= w * 1.5) return { padding: S(def, s) };
  return { paddingTop: S(260, s), paddingBottom: S(420, s), paddingLeft: S(def, s), paddingRight: S(160, s) };
}

function Logo({ pos, bg, scale = 1 }) {
  if (pos === 'none') return null;
  const onDark = bg !== 'paper';
  const res = window.__resources || {};
  const src = res[onDark ? 'logoWhite' : 'logo'] || (onDark ? 'assets/logo_white.png' : 'assets/logo.png');
  const invert = onDark && res.invertOnDark;
  const lScale = res.logoScale || 1;
  const offset = S(72, scale);
  const positions = {
    tl: { top: offset, left: offset },
    tc: { top: offset, left: '50%', transform: 'translateX(-50%)' },
    tr: { top: offset, right: offset },
    bl: { bottom: offset, left: offset },
    bc: { bottom: offset, left: '50%', transform: 'translateX(-50%)' },
    br: { bottom: offset, right: offset },
  };
  return (
    <img src={src} alt="Brand" style={{
      position: 'absolute',
      ...positions[pos],
      height: S(36 * lScale, scale), width: 'auto',
      filter: invert ? 'brightness(0) invert(1)' : undefined,
    }} />
  );
}

function BrandingWatermark({ slide, bg, s }) {
  const res = window.__resources || {};
  const text = slide.footer || res.website || '';
  if (!text) return null;
  const bPos = res.brandingPos || 'bl';
  const bScale = res.brandingScale || 1;
  const o = S(56, s);
  const h = S(88, s);
  const posMap = {
    tl: { top: o, left: h },
    tc: { top: o, left: '50%', transform: 'translateX(-50%)' },
    tr: { top: o, right: h },
    bl: { bottom: o, left: h },
    bc: { bottom: o, left: '50%', transform: 'translateX(-50%)' },
    br: { bottom: o, right: h },
  };
  return (
    <div style={{
      position: 'absolute',
      ...(posMap[bPos] || posMap.bl),
      fontSize: S(18 * bScale, s),
      color: muted(bg), fontWeight: 500,
    }}>{text}</div>
  );
}

function Eyebrow({ children, bg, accent: isAccent, s = 1 }) {
  if (!children) return null;
  return (
    <div style={{
      fontSize: S(18, s), fontWeight: 600, letterSpacing: '0.16em',
      textTransform: 'uppercase',
      color: isAccent ? accent(bg) : muted(bg),
      marginBottom: S(24, s),
      display: 'flex', alignItems: 'center', gap: S(12, s),
    }}>
      <span style={{ display: 'inline-block', width: S(24, s), height: 2, background: 'currentColor' }}></span>
      {children}
    </div>
  );
}

function Footer({ slide, bg, index, total, lang, s = 1, showPage = true, showBranding = true }) {
  return (
    <>
      {showBranding && <BrandingWatermark slide={slide} bg={bg} s={s} />}
      {showPage && total > 1 && (
        <div style={{
          position: 'absolute', right: S(88, s), bottom: S(64, s),
          fontSize: S(18, s), color: muted(bg),
          fontFamily: 'var(--ml-font-mono)', letterSpacing: '0.04em',
        }}>
          {String(index + 1).padStart(2, '0')} / {String(total).padStart(2, '0')}
        </div>
      )}
    </>
  );
}

// ============================================================
// 01. COVER
// ============================================================
function LayoutCover({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const isPortrait = height > width * 1.2;
  const hasVideo = slide.video && slide.video.url;
  const rootBg = hasVideo
    ? { background: '#0e0e0f', color: 'white' }
    : bgStyle(bg, slide.image, overlayOpacity);
  const effectiveBg = hasVideo ? 'image' : bg;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...rootBg }}>
      {hasVideo && <BgVideo video={slide.video} overlayOpacity={overlayOpacity} />}
      <div style={{
        position: 'absolute', inset: 0, zIndex: 1,
        ...szPad(width, height, s, 88),
        display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
      }}>
        <Logo pos={logoPos} bg={effectiveBg} scale={s} />
        <div style={{ maxWidth: isPortrait ? '100%' : '88%' }}>
          <Eyebrow bg={effectiveBg} accent s={s}>{slide.eyebrow}</Eyebrow>
          <h1 style={{
            margin: 0,
            fontSize: S(isPortrait ? 108 : 132, ts),
            fontWeight: 700, lineHeight: 1.08,
            letterSpacing: '-0.028em',
            textWrap: 'balance',
          }}>{slide.title}</h1>
          {slide.body && (
            <p style={{
              margin: `${S(40, s)}px 0 0`,
              fontSize: S(32, ts), lineHeight: 1.4,
              fontWeight: 400, color: muted(effectiveBg),
              maxWidth: '80%', letterSpacing: '-0.005em',
            }}>{slide.body}</p>
          )}
          {slide.cta && (
            <div style={{
              marginTop: S(48, s),
              display: 'inline-flex', alignItems: 'center', gap: S(14, s),
              fontSize: S(26, ts), fontWeight: 600, color: accent(effectiveBg),
            }}>
              {slide.cta} <span style={{ fontSize: S(30, ts) }}>→</span>
            </div>
          )}
        </div>
        <Footer slide={slide} bg={effectiveBg} index={index} total={total} lang={lang} s={s} showPage={false} showBranding={showBranding} />
      </div>
    </div>
  );
}

// ============================================================
// 02. STATEMENT
// ============================================================
function LayoutStatement({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const isLandscape = width > height * 1.4;
  const hasVideo = slide.video && slide.video.url;
  const rootBg = hasVideo ? { background: '#0e0e0f', color: 'white' } : bgStyle(bg, slide.image, overlayOpacity);
  const effectiveBg = hasVideo ? 'image' : bg;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...rootBg }}>
      {hasVideo && <BgVideo video={slide.video} overlayOpacity={overlayOpacity} />}
      <div style={{
        position: 'absolute', inset: 0, zIndex: 1,
        ...szPad(width, height, s, 96),
        display: 'flex', flexDirection: 'column', justifyContent: 'center',
      }}>
        <Logo pos={logoPos} bg={effectiveBg} scale={s} />
        {slide.eyebrow && <Eyebrow bg={effectiveBg} accent s={s}>{slide.eyebrow}</Eyebrow>}
        <h1 style={{
          margin: 0,
          fontSize: S(isLandscape ? 88 : 112, ts),
          fontWeight: 700, lineHeight: 1.05,
          letterSpacing: '-0.03em', textWrap: 'balance',
          maxWidth: isLandscape ? '70%' : '100%',
        }}>{slide.title}</h1>
        {slide.body && (
          <p style={{
            margin: `${S(48, s)}px 0 0`,
            fontSize: S(28, ts), lineHeight: 1.4,
            color: muted(effectiveBg), maxWidth: '85%',
          }}>{slide.body}</p>
        )}
        {slide.cta && (
          <div style={{
            marginTop: S(36, s), display: 'inline-flex', alignItems: 'center',
            gap: S(12, s), fontSize: S(24, ts), fontWeight: 600, color: accent(effectiveBg),
          }}>{slide.cta} <span>→</span></div>
        )}
        <Footer slide={slide} bg={effectiveBg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
      </div>
    </div>
  );
}

// ============================================================
// 03. QUOTE
// ============================================================
function LayoutQuote({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: 'flex', flexDirection: 'column', justifyContent: 'center', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <div style={{
        fontSize: S(140, ts), lineHeight: 0.7, fontWeight: 700,
        color: accent(bg), marginBottom: 0,
        fontFamily: 'Georgia, serif',
      }}>"</div>
      <p style={{
        margin: `${S(8, s)}px 0 0`,
        fontSize: S(52, ts), fontWeight: 500, lineHeight: 1.22,
        letterSpacing: '-0.02em', textWrap: 'balance',
        maxWidth: '90%',
      }}>{slide.quote || slide.title}</p>
      {slide.author && (
        <div style={{
          marginTop: S(56, s), display: 'flex', alignItems: 'center', gap: S(16, s),
        }}>
          <span style={{ display: 'inline-block', width: S(48, s), height: 2, background: accent(bg) }}></span>
          <span style={{ fontSize: S(24, ts), fontWeight: 600 }}>{slide.author}</span>
          {slide.body && <span style={{ fontSize: S(20, ts), color: muted(bg) }}>· {slide.body}</span>}
        </div>
      )}
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 04. STAT
// ============================================================
function LayoutStat({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const isLandscape = width > height * 1.4;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: isLandscape ? 'grid' : 'flex', gridTemplateColumns: isLandscape ? '1fr 1fr' : '', alignItems: 'center', gap: S(48, s), flexDirection: 'column', justifyContent: 'center', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <div>
        {!isLandscape && slide.eyebrow && <Eyebrow bg={bg} accent s={s}>{slide.eyebrow}</Eyebrow>}
        <div style={{
          fontSize: S(isLandscape ? 180 : 240, ts),
          fontWeight: 700, lineHeight: 0.85,
          letterSpacing: '-0.04em', color: accent(bg),
        }}>
          {slide.stat || '23+'}
        </div>
      </div>
      <div>
        {isLandscape && slide.eyebrow && <Eyebrow bg={bg} accent s={s}>{slide.eyebrow}</Eyebrow>}
        <div style={{
          marginTop: isLandscape ? 0 : S(40, s),
          fontSize: S(isLandscape ? 52 : 44, ts),
          fontWeight: 600,
          lineHeight: 1.22, letterSpacing: '-0.015em',
          textWrap: 'balance', maxWidth: '95%',
        }}>{slide.statLabel || slide.title}</div>
        {slide.body && (
          <p style={{
            margin: `${S(28, s)}px 0 0`,
            fontSize: S(24, ts), lineHeight: 1.45,
            color: muted(bg), maxWidth: '92%',
          }}>{slide.body}</p>
        )}
      </div>
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 05. NUMBERED LIST
// ============================================================
function LayoutList({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const items = (slide.items && slide.items.length) ? slide.items : ['Madde bir', 'Madde iki', 'Madde üç'];
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: 'flex', flexDirection: 'column', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      {slide.eyebrow && <Eyebrow bg={bg} accent s={s}>{slide.eyebrow}</Eyebrow>}
      <h2 style={{
        margin: 0,
        fontSize: S(60, ts), fontWeight: 700, lineHeight: 1.15,
        letterSpacing: '-0.022em', textWrap: 'balance',
        maxWidth: '85%',
      }}>{slide.title}</h2>
      {slide.body && (
        <p style={{
          margin: `${S(20, s)}px 0 0`,
          fontSize: S(22, ts), lineHeight: 1.4,
          color: muted(bg), maxWidth: '90%',
        }}>{slide.body}</p>
      )}
      <div style={{ marginTop: S(48, s), display: 'flex', flexDirection: 'column', gap: S(24, s) }}>
        {items.slice(0, 5).map((item, i) => (
          <div key={i} style={{
            display: 'flex', alignItems: 'flex-start', gap: S(28, s),
            paddingTop: S(24, s), borderTop: `1px solid ${line(bg)}`,
          }}>
            <span style={{
              fontSize: S(26, ts), fontWeight: 600, fontFamily: 'var(--ml-font-mono)',
              color: accent(bg), minWidth: S(56, s),
              letterSpacing: '-0.02em',
            }}>0{i + 1}</span>
            <span style={{
              fontSize: S(30, ts), lineHeight: 1.3,
              letterSpacing: '-0.012em', fontWeight: 500,
              flex: 1,
            }}>{item}</span>
          </div>
        ))}
      </div>
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 06. SPLIT
// ============================================================
function LayoutSplit({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', display: 'flex', ...bgStyle(bg) }}>
      <div style={{ flex: 1, padding: S(88, s), display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
        {slide.eyebrow && <Eyebrow bg={bg} accent s={s}>{slide.eyebrow}</Eyebrow>}
        <h2 style={{
          margin: 0,
          fontSize: S(80, ts), fontWeight: 700, lineHeight: 1.08,
          letterSpacing: '-0.028em', textWrap: 'balance',
        }}>{slide.title}</h2>
        {slide.body && (
          <p style={{
            margin: `${S(32, s)}px 0 0`,
            fontSize: S(24, ts), lineHeight: 1.45,
            color: muted(bg),
          }}>{slide.body}</p>
        )}
        {slide.cta && (
          <div style={{
            marginTop: S(40, s),
            display: 'inline-flex', alignItems: 'center', gap: S(12, s),
            fontSize: S(22, ts), fontWeight: 600, color: accent(bg),
          }}>{slide.cta} →</div>
        )}
      </div>
      <div style={{
        flex: 1, background: slide.image ? `url(${slide.image}) center/cover` : 'var(--ml-ink)',
        position: 'relative',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {!slide.image && (
          <div style={{
            color: 'rgba(255,255,255,0.4)', fontSize: S(18, ts),
            fontFamily: 'var(--ml-font-mono)', letterSpacing: '0.08em',
            textTransform: 'uppercase',
          }}>Image area</div>
        )}
      </div>
      <Logo pos={logoPos} bg={bg} scale={s} />
      {showBranding && <BrandingWatermark slide={slide} bg={bg} s={s} />}
      {total > 1 && width >= height && (
        <div style={{
          position: 'absolute', right: S(88, s), bottom: S(56, s),
          fontSize: S(18, ts), color: 'rgba(255,255,255,0.7)',
          fontFamily: 'var(--ml-font-mono)', letterSpacing: '0.04em',
        }}>{String(index + 1).padStart(2, '0')} / {String(total).padStart(2, '0')}</div>
      )}
    </div>
  );
}

// ============================================================
// 07. Q&A
// ============================================================
function LayoutQA({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: 'flex', flexDirection: 'column', justifyContent: 'center', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <div style={{
        fontSize: S(24, ts), fontWeight: 600, color: accent(bg),
        fontFamily: 'var(--ml-font-mono)', letterSpacing: '0.08em',
        textTransform: 'uppercase', marginBottom: S(28, s),
      }}>{lang === 'tr' ? 'Soru' : 'Question'}</div>
      <h2 style={{
        margin: 0,
        fontSize: S(60, ts), fontWeight: 700, lineHeight: 1.18,
        letterSpacing: '-0.02em', textWrap: 'balance',
        maxWidth: '92%',
      }}>{slide.question || slide.title}</h2>
      <div style={{
        margin: `${S(48, s)}px 0 ${S(20, s)}px`,
        fontSize: S(20, ts), fontWeight: 600, color: muted(bg),
        fontFamily: 'var(--ml-font-mono)', letterSpacing: '0.08em',
        textTransform: 'uppercase',
        display: 'flex', alignItems: 'center', gap: S(16, s),
      }}>
        <span style={{ display: 'inline-block', width: S(32, s), height: 1, background: 'currentColor' }}></span>
        {lang === 'tr' ? 'Cevap' : 'Answer'}
      </div>
      <p style={{
        margin: 0,
        fontSize: S(30, ts), lineHeight: 1.4, fontWeight: 400,
        letterSpacing: '-0.008em',
        maxWidth: '92%',
      }}>{slide.answer || slide.body}</p>
      {slide.cta && (
        <div style={{
          marginTop: S(36, s), display: 'inline-flex', alignItems: 'center',
          gap: S(12, s), fontSize: S(22, ts), fontWeight: 600, color: accent(bg),
        }}>{slide.cta} <span>→</span></div>
      )}
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 08. STEP
// ============================================================
function LayoutStep({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const isLandscape = width > height * 1.4;
  const stepNum = slide.stat || String(index).padStart(2, '0');
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: isLandscape ? 'grid' : 'flex', gridTemplateColumns: isLandscape ? '1fr 1fr' : '', alignItems: isLandscape ? 'center' : '', flexDirection: 'column', justifyContent: 'space-between', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <div>
        <div style={{
          fontSize: S(20, ts), fontWeight: 600, letterSpacing: '0.12em',
          textTransform: 'uppercase', color: muted(bg), marginBottom: S(16, s),
        }}>{slide.eyebrow || (lang === 'tr' ? 'Adım' : 'Step')}</div>
        <div style={{
          fontSize: S(isLandscape ? 140 : 180, ts),
          fontWeight: 700, lineHeight: 0.85,
          color: accent(bg), letterSpacing: '-0.04em',
        }}>{stepNum}</div>
      </div>
      <div style={{ marginBottom: isLandscape ? 0 : S(80, s) }}>
        <h2 style={{
          margin: 0,
          fontSize: S(isLandscape ? 56 : 60, ts),
          fontWeight: 700, lineHeight: 1.15,
          letterSpacing: '-0.022em', textWrap: 'balance',
          maxWidth: '95%',
        }}>{slide.title}</h2>
        {slide.body && (
          <p style={{
            margin: `${S(24, s)}px 0 0`,
            fontSize: S(24, ts), lineHeight: 1.45,
            color: muted(bg), maxWidth: '92%',
          }}>{slide.body}</p>
        )}
        {slide.cta && (
          <div style={{
            marginTop: S(28, s), display: 'inline-flex', alignItems: 'center',
            gap: S(12, s), fontSize: S(22, ts), fontWeight: 600, color: accent(bg),
          }}>{slide.cta} <span>→</span></div>
        )}
      </div>
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 09. PHOTO HERO
// ============================================================
function LayoutPhotoHero({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const hasVideo = slide.video && slide.video.url;
  const imgBg = hasVideo
    ? { background: '#0e0e0f' }
    : (slide.image
        ? { backgroundImage: `linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.65) 70%, rgba(0,0,0,0.85) 100%), url(${slide.image})`, backgroundSize: 'cover', backgroundPosition: 'center' }
        : { background: 'linear-gradient(180deg, #4a5568, #1a202c)' });
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', color: 'white', ...imgBg }}>
      {hasVideo && <BgVideo video={slide.video} overlayOpacity={overlayOpacity} />}
      <div style={{
        position: 'absolute', inset: 0, zIndex: 1,
        ...szPad(width, height, s, 88),
        display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
      }}>
        <Logo pos={logoPos} bg="image" scale={s} />
        <Eyebrow bg="ink" accent s={s}>{slide.eyebrow}</Eyebrow>
        <h1 style={{
          margin: 0,
          fontSize: S(88, ts), fontWeight: 700, lineHeight: 1.08,
          letterSpacing: '-0.025em', textWrap: 'balance',
          maxWidth: '90%',
        }}>{slide.title}</h1>
        {slide.body && (
          <p style={{
            margin: `${S(28, s)}px 0 0`,
            fontSize: S(24, ts), lineHeight: 1.45,
            color: 'rgba(255,255,255,0.85)',
            maxWidth: '85%',
          }}>{slide.body}</p>
        )}
        {slide.cta && (
          <div style={{
            marginTop: S(28, s), display: 'inline-flex', alignItems: 'center',
            gap: S(12, s), fontSize: S(22, ts), fontWeight: 600, color: 'var(--ml-red)',
          }}>{slide.cta} <span>→</span></div>
        )}
        <Footer slide={slide} bg="ink" index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
      </div>
    </div>
  );
}

// ============================================================
// 10. PLATFORM
// ============================================================
function LayoutPlatform({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 88), display: 'flex', flexDirection: 'column', justifyContent: 'center', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <Eyebrow bg={bg} accent s={s}>{slide.eyebrow || (lang === 'tr' ? 'Platform' : 'Platform')}</Eyebrow>
      {(() => { const res = window.__resources || {}; const txt = slide.footer || res.website || ''; return (showBranding || slide.footer) && txt ? (
        <div style={{
          display: 'inline-block', padding: `${S(6, s)}px ${S(16, s)}px`,
          background: accent(bg),
          color: bg === 'red' ? 'var(--ml-red)' : 'white',
          borderRadius: 999,
          fontSize: S(18, ts), fontWeight: 600,
          marginBottom: S(28, s), alignSelf: 'flex-start',
          fontFamily: 'var(--ml-font-mono)',
        }}>{txt}</div>
      ) : null; })()}
      <h2 style={{
        margin: 0,
        fontSize: S(80, ts), fontWeight: 700, lineHeight: 1.06,
        letterSpacing: '-0.025em', textWrap: 'balance',
        maxWidth: '95%',
      }}>{slide.title}</h2>
      {slide.body && (
        <p style={{
          margin: `${S(32, s)}px 0 0`,
          fontSize: S(26, ts), lineHeight: 1.4,
          color: muted(bg), maxWidth: '88%',
        }}>{slide.body}</p>
      )}
      {slide.items && slide.items.length > 0 && (
        <div style={{
          marginTop: S(40, s), display: 'flex', flexWrap: 'wrap', gap: S(12, s),
        }}>
          {slide.items.slice(0, 6).map((tag, i) => (
            <span key={i} style={{
              padding: `${S(8, s)}px ${S(20, s)}px`, borderRadius: 999,
              border: `1px solid ${line(bg)}`,
              fontSize: S(18, ts), fontWeight: 500, color: muted(bg),
            }}>{tag}</span>
          ))}
        </div>
      )}
      {slide.cta && (
        <div style={{
          marginTop: S(36, s), display: 'inline-flex', alignItems: 'center',
          gap: S(12, s), fontSize: S(22, ts), fontWeight: 600, color: accent(bg),
        }}>{slide.cta} <span>→</span></div>
      )}
      {showBranding && <BrandingWatermark slide={slide} bg={bg} s={s} />}
      {total > 1 && width >= height && (
        <div style={{
          position: 'absolute', right: S(88, s), bottom: S(56, s),
          fontSize: S(18, ts), color: muted(bg),
          fontFamily: 'var(--ml-font-mono)',
        }}>{String(index + 1).padStart(2, '0')} / {String(total).padStart(2, '0')}</div>
      )}
    </div>
  );
}

// ============================================================
// 11. INDEX
// ============================================================
function LayoutIndex({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const items = (slide.items && slide.items.length) ? slide.items : ['Konu bir', 'Konu iki', 'Konu üç'];
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: 'flex', flexDirection: 'column', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      <Eyebrow bg={bg} accent s={s}>{slide.eyebrow || (lang === 'tr' ? 'İçindekiler' : 'Contents')}</Eyebrow>
      <h2 style={{
        margin: 0,
        fontSize: S(72, ts), fontWeight: 700, lineHeight: 1.15,
        letterSpacing: '-0.025em', textWrap: 'balance',
        maxWidth: '85%',
      }}>{slide.title}</h2>
      {slide.body && (
        <p style={{
          margin: `${S(16, s)}px 0 0`,
          fontSize: S(22, ts), lineHeight: 1.4,
          color: muted(bg), maxWidth: '90%',
        }}>{slide.body}</p>
      )}
      <div style={{ marginTop: S(56, s), flex: 1 }}>
        {items.slice(0, 6).map((item, i) => (
          <div key={i} style={{
            display: 'flex', alignItems: 'baseline', gap: S(32, s),
            padding: `${S(20, s)}px 0`, borderTop: `1px solid ${line(bg)}`,
          }}>
            <span style={{
              fontSize: S(20, ts), fontFamily: 'var(--ml-font-mono)',
              color: muted(bg), letterSpacing: '0.02em',
              minWidth: S(48, s),
            }}>{String(i + 1).padStart(2, '0')}</span>
            <span style={{
              fontSize: S(32, ts), fontWeight: 500, letterSpacing: '-0.012em',
              flex: 1,
            }}>{item}</span>
            <span style={{ color: accent(bg), fontSize: S(28, ts) }}>→</span>
          </div>
        ))}
      </div>
      {slide.cta && (
        <div style={{
          marginTop: S(28, s), display: 'inline-flex', alignItems: 'center',
          gap: S(12, s), fontSize: S(22, ts), fontWeight: 600, color: accent(bg),
        }}>{slide.cta} <span>→</span></div>
      )}
      <Footer slide={slide} bg={bg} index={index} total={total} lang={lang} s={s} showPage={width >= height} showBranding={showBranding} />
    </div>
  );
}

// ============================================================
// 12. CTA
// ============================================================
function LayoutCTA({ slide, bg, logoPos, index, total, width, height, lang, showBranding = true, textScale = 1, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const ts = s * textScale;
  const isLandscape = width > height * 1.4;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', ...szPad(width, height, s, 96), display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'flex-start', ...bgStyle(bg, slide.image, overlayOpacity) }}>
      <Logo pos={logoPos} bg={bg} scale={s} />
      {slide.eyebrow && <Eyebrow bg={bg} accent s={s}>{slide.eyebrow}</Eyebrow>}
      <h2 style={{
        margin: 0,
        fontSize: S(isLandscape ? 76 : 92, ts),
        fontWeight: 700, lineHeight: 1.1,
        letterSpacing: '-0.028em', textWrap: 'balance',
        maxWidth: '95%',
      }}>{slide.title}</h2>
      {slide.body && (
        <p style={{
          margin: `${S(28, s)}px 0 0`,
          fontSize: S(26, ts), lineHeight: 1.45,
          color: muted(bg), maxWidth: '88%',
        }}>{slide.body}</p>
      )}
      {slide.cta && (
        <div style={{
          marginTop: S(44, s),
          display: 'inline-flex', alignItems: 'center', gap: S(16, s),
          padding: `${S(20, s)}px ${S(32, s)}px`,
          background: accent(bg),
          color: bg === 'red' ? 'var(--ml-red)' : 'white',
          borderRadius: 999,
          fontSize: S(28, ts), fontWeight: 600,
          letterSpacing: '-0.01em',
        }}>{slide.cta} <span style={{ fontSize: S(30, ts) }}>→</span></div>
      )}
      {showBranding && <BrandingWatermark slide={slide} bg={bg} s={s} />}
    </div>
  );
}

// ============================================================
// IMAGE + LOGO (sadece görsel ve logo, metinsiz) — 3 varyant
// ============================================================
function _imageLogoSrc(onDark) {
  const res = window.__resources || {};
  return {
    src: res[onDark ? 'logoWhite' : 'logo'] || (onDark ? 'assets/logo_white.png' : 'assets/logo.png'),
    invert: onDark && res.invertOnDark,
    lScale: res.logoScale || 1,
  };
}
function _imageFill(slide) {
  const hasVideo = slide.video && slide.video.url;
  if (hasVideo) return { background: '#0e0e0f' };
  if (slide.image) return {
    backgroundImage: `url(${slide.image})`, backgroundSize: 'cover', backgroundPosition: 'center',
  };
  return { background: 'linear-gradient(180deg, #4a5568, #1a202c)' };
}

function LayoutImageLogo({ slide, width, height, showBranding = true }) {
  const s = aspectScale(width, height);
  const imgH = Math.round(height * 0.75);
  const stripH = height - imgH;
  const { src, invert, lScale } = _imageLogoSrc(false);
  const hasVideo = slide.video && slide.video.url;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', background: 'var(--ml-paper)' }}>
      <div style={{ position: 'absolute', left: 0, right: 0, top: 0, height: imgH, overflow: 'hidden', ..._imageFill(slide) }}>
        {hasVideo && <BgVideo video={slide.video} overlayOpacity={0} />}
      </div>
      <div style={{
        position: 'absolute', left: 0, right: 0, top: imgH, height: stripH,
        background: 'var(--ml-paper)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <img src={src} alt="Brand" style={{
          height: Math.round(stripH * 0.55 * lScale),
          maxHeight: stripH - S(24, s),
          maxWidth: width - S(160, s),
          width: 'auto', objectFit: 'contain',
          filter: invert ? 'brightness(0) invert(1)' : undefined,
        }} />
      </div>
      {showBranding && <BrandingWatermark slide={slide} bg="paper" s={s} />}
    </div>
  );
}

function LayoutImageLogoOverlay({ slide, width, height, overlayOpacity = 0.5 }) {
  const s = aspectScale(width, height);
  const stripH = Math.round(height * 0.22);
  const { src, invert, lScale } = _imageLogoSrc(true);
  const hasVideo = slide.video && slide.video.url;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', color: 'white', ..._imageFill(slide) }}>
      {hasVideo && <BgVideo video={slide.video} overlayOpacity={overlayOpacity} />}
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, height: stripH,
        background: 'linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.55) 45%, rgba(0,0,0,0.85) 100%)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        zIndex: 2,
      }}>
        <img src={src} alt="Brand" style={{
          height: Math.round(stripH * 0.55 * lScale),
          maxHeight: stripH - S(24, s),
          maxWidth: width - S(160, s),
          width: 'auto', objectFit: 'contain',
          filter: invert ? 'brightness(0) invert(1)' : undefined,
        }} />
      </div>
    </div>
  );
}

function LayoutImageLogoSlim({ slide, width, height, showBranding = true }) {
  const s = aspectScale(width, height);
  const imgH = Math.round(height * 0.85);
  const stripH = height - imgH;
  const { src, invert, lScale } = _imageLogoSrc(false);
  const hasVideo = slide.video && slide.video.url;
  return (
    <div style={{ width, height, position: 'relative', overflow: 'hidden', background: 'var(--ml-paper)' }}>
      <div style={{ position: 'absolute', left: 0, right: 0, top: 0, height: imgH, overflow: 'hidden', ..._imageFill(slide) }}>
        {hasVideo && <BgVideo video={slide.video} overlayOpacity={0} />}
      </div>
      <div style={{
        position: 'absolute', left: 0, right: 0, top: imgH, height: stripH,
        background: 'var(--ml-paper)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        borderTop: '1px solid var(--ml-line)',
      }}>
        <img src={src} alt="Brand" style={{
          height: Math.round(stripH * 0.5 * lScale),
          maxHeight: stripH - S(12, s),
          maxWidth: width - S(160, s),
          width: 'auto', objectFit: 'contain',
          filter: invert ? 'brightness(0) invert(1)' : undefined,
        }} />
      </div>
      {showBranding && <BrandingWatermark slide={slide} bg="paper" s={s} />}
    </div>
  );
}

// ============================================================
// Export the layout registry
// ============================================================
const LAYOUTS = [
  { id: 'cover', name: 'Cover', component: LayoutCover, desc: 'Eyebrow + display headline' },
  { id: 'statement', name: 'Statement', component: LayoutStatement, desc: 'Massive typographic' },
  { id: 'quote', name: 'Quote', component: LayoutQuote, desc: 'Pull-quote + attribution' },
  { id: 'stat', name: 'Stat', component: LayoutStat, desc: 'Big number + label' },
  { id: 'list', name: 'List', component: LayoutList, desc: 'Numbered items' },
  { id: 'split', name: 'Split', component: LayoutSplit, desc: 'Text + image side' },
  { id: 'qa', name: 'Q & A', component: LayoutQA, desc: 'Question + answer' },
  { id: 'step', name: 'Step', component: LayoutStep, desc: 'Numbered step card' },
  { id: 'photo', name: 'Photo Hero', component: LayoutPhotoHero, desc: 'Full-bleed image' },
  { id: 'platform', name: 'Platform', component: LayoutPlatform, desc: 'Service / platform card' },
  { id: 'index', name: 'Index', component: LayoutIndex, desc: 'Agenda / contents' },
  { id: 'cta', name: 'CTA', component: LayoutCTA, desc: 'End card with action' },
  { id: 'image-logo',         name: 'Image + Logo',         component: LayoutImageLogo,        desc: 'Görsel üstte, alt şeritte logo' },
  { id: 'image-logo-overlay', name: 'Image + Overlay Logo', component: LayoutImageLogoOverlay, desc: 'Tam görsel, altta overlay logo' },
  { id: 'image-logo-slim',    name: 'Image + Slim Logo',    component: LayoutImageLogoSlim,    desc: 'Görsel ağırlıklı, ince logo şeridi' },
];

function renderLayout(layoutId, props) {
  const entry = LAYOUTS.find(l => l.id === layoutId) || LAYOUTS[0];
  const Comp = entry.component;
  return <Comp {...props} />;
}

window.LAYOUTS = LAYOUTS;
window.renderLayout = renderLayout;
