// flow.jsx — core flow: Detail, story-generation Loading, PostPlay. (Player is player.jsx.)
(function () {
  const T = window.T, { Btn, Eyebrow, ImgSlot, IconBtn } = window;
  const { useState, useEffect } = React;

  // pick assigned voice from user's interests
  window.pickVoice = function (app) {
    const order = app.interests || [];
    for (const id of order) if (window.VOICES[id]) return { v: window.VOICES[id], it: id };
    // map other interests to a near voice
    const fallbackMap = { food: 'daily', art: 'arch', rite: 'royal', garden: 'arch', women: 'royal', science: 'arch' };
    for (const id of order) if (fallbackMap[id]) return { v: window.VOICES[fallbackMap[id]], it: fallbackMap[id] };
    return { v: window.VOICES.royal, it: 'royal' };
  };

  function VoiceChip({ app, dark, onWhy }) {
    const { v } = window.pickVoice(app);
    return (
      <button onClick={onWhy} style={{ display: 'flex', alignItems: 'center', gap: 11, cursor: 'pointer',
        background: dark ? 'rgba(246,240,227,.08)' : T.soft, border: '1px solid ' + (dark ? 'rgba(246,240,227,.14)' : T.hairlineSoft),
        borderRadius: 99, padding: '7px 14px 7px 8px', textAlign: 'left' }}>
        <div style={{ width: 36, height: 36, borderRadius: 99, background: dark ? T.tealEl : T.teal,
          display: 'grid', placeItems: 'center', flexShrink: 0, boxShadow: 'inset 0 0 0 1.5px ' + T.gold }}>
          <Icon name="speaker" size={18} color={T.gold} stroke={1.8} /></div>
        <div>
          <div style={{ fontFamily: T.sans, fontSize: 10.5, fontWeight: 700, letterSpacing: .8,
            textTransform: 'uppercase', color: dark ? T.gold : T.goldDim }}>AI 배정 보이스</div>
          <div style={{ fontFamily: T.sans, fontSize: 14, fontWeight: 600, color: dark ? T.onDark : T.ink,
            marginTop: 1, whiteSpace: 'nowrap' }}>{v.name} · {v.role}</div>
        </div>
        <Icon name="sparkle" size={16} color={dark ? T.gold : T.goldDim} style={{ marginLeft: 4 }} />
      </button>
    );
  }
  window.VoiceChip = VoiceChip;

  // ── Detail ──────────────────────────────────────────────────
  function Detail({ go, app, params, set }) {
    const s = window.siteById(params.id) || window.SITES[0];
    const saved = app.saved?.includes(s.id);
    const { v, it } = window.pickVoice(app);
    const lens = window.INTERESTS.find(i => i.id === it);
    const lang = window.LANGS.find(l => l.code === app.lang) || window.LANGS[0];
    const [why, setWhy] = useState(false);
    return (
      <div style={{ position: 'absolute', inset: 0, background: T.canvas, overflow: 'hidden',
        display: 'flex', flexDirection: 'column' }}>
        <div style={{ flex: 1, overflowY: 'auto', scrollbarWidth: 'none' }}>
          {/* hero */}
          <div style={{ position: 'relative' }}>
            <ImgSlot label={s.full + ' · 대표 이미지'} h={300} r={0} />
            <div style={{ position: 'absolute', inset: 0, background:
              'linear-gradient(to bottom, rgba(33,30,20,.28), transparent 28%, transparent 70%, rgba(251,246,236,.95))' }} />
            <div style={{ position: 'absolute', top: 14, left: 16, right: 16, display: 'flex',
              justifyContent: 'space-between' }}>
              <IconBtn name="chevronL" onClick={() => go('back')} bg="rgba(251,246,236,.92)" />
              <div style={{ display: 'flex', gap: 8 }}>
                <IconBtn name="share" bg="rgba(251,246,236,.92)" />
                <IconBtn name="bookmark" bg="rgba(251,246,236,.92)" color={saved ? T.gold : T.ink}
                  onClick={() => set({ saved: saved ? app.saved.filter(x => x !== s.id) : [...(app.saved || []), s.id] })} />
              </div>
            </div>
          </div>

          <div style={{ padding: '4px 24px 18px', marginTop: -4 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 9 }}>
              <span style={{ fontFamily: T.sans, fontSize: 12, fontWeight: 700, color: T.gold,
                background: '#f3e6c4', padding: '4px 10px', borderRadius: 99 }}>{s.stat}</span>
              <span style={{ fontFamily: T.sans, fontSize: 12.5, color: T.muted }}>{s.type}</span>
            </div>
            <h1 style={{ fontFamily: T.display, fontSize: 32, letterSpacing: -.8, color: T.ink, margin: 0 }}>{s.full}</h1>
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, margin: '10px 0 0' }}>
              <Meta icon="clock" text={s.period} />
              <Meta icon="pin" text={`${s.dist}m · 도보 ${s.min}분`} />
            </div>
            <p style={{ fontFamily: T.sans, fontSize: 15.5, lineHeight: 1.68, color: T.body, margin: '18px 0 0' }}>
              {s.intro}</p>

            {/* personalized story note */}
            <div style={{ marginTop: 22, background: T.soft, border: '1px solid ' + T.hairlineSoft,
              borderRadius: T.r.lg, padding: '16px 16px 14px' }}>
              <Eyebrow color={T.goldDim}>당신을 위한 구성</Eyebrow>
              <p style={{ fontFamily: T.sans, fontSize: 14, lineHeight: 1.6, color: T.body, margin: '10px 0 14px' }}>
                <b style={{ color: T.ink }}>{lens ? '‘' + lens.label + '’' : '당신의 관심사'}</b> 관점으로 해설을 엮고, 그에 어울리는 목소리를 골랐어요.</p>
              <VoiceChip app={app} onWhy={() => setWhy(true)} />
            </div>

            {/* language row */}
            <button onClick={() => go('langPick')} style={{ width: '100%', marginTop: 12, cursor: 'pointer',
              background: 'none', border: '1px solid ' + T.hairline, borderRadius: T.r.lg, padding: '14px 16px',
              display: 'flex', alignItems: 'center', gap: 12 }}>
              <Icon name="globe" size={20} color={T.teal} />
              <span style={{ flex: 1, textAlign: 'left', fontFamily: T.sans, fontSize: 14.5, fontWeight: 600,
                color: T.ink }}>청취 언어</span>
              <span style={{ fontFamily: T.sans, fontSize: 13.5, color: T.muted }}>{lang.native}</span>
              <Icon name="chevronR" size={17} color={T.mutedSoft} />
            </button>
          </div>
        </div>

        {/* sticky CTA */}
        <div style={{ flexShrink: 0, padding: '12px 24px 26px', borderTop: '1px solid ' + T.hairlineSoft,
          background: T.canvas, display: 'flex', gap: 12, alignItems: 'center' }}>
          <div style={{ flexShrink: 0, whiteSpace: 'nowrap' }}>
            <div style={{ fontFamily: T.sans, fontSize: 12, color: T.muted }}>예상 청취</div>
            <div style={{ fontFamily: T.display, fontSize: 18, color: T.ink, letterSpacing: -.3 }}>약 6분</div>
          </div>
          <Btn full kind="primary" icon="headphones" onClick={() => go('loading', { id: s.id })}>이야기 듣기</Btn>
        </div>

        {why && <WhySheet v={v} lens={lens} onClose={() => setWhy(false)} />}
      </div>
    );
  }
  function Meta({ icon, text }) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 5, whiteSpace: 'nowrap' }}>
        <Icon name={icon} size={15} color={T.muted} />
        <span style={{ fontFamily: T.sans, fontSize: 13, color: T.muted }}>{text}</span>
      </div>
    );
  }
  function WhySheet({ v, lens, onClose }) {
    return (
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 40, background: 'rgba(24,30,26,.4)',
        display: 'flex', alignItems: 'flex-end', animation: 'munaFade .2s ease' }}>
        <div onClick={e => e.stopPropagation()} style={{ width: '100%', background: T.canvas,
          borderRadius: '22px 22px 0 0', padding: '12px 24px 30px', animation: 'munaRise .3s ease' }}>
          <div style={{ width: 40, height: 5, borderRadius: 9, background: T.hairline, margin: '0 auto 18px' }} />
          <div style={{ width: 56, height: 56, borderRadius: 18, background: T.teal, display: 'grid',
            placeItems: 'center', boxShadow: 'inset 0 0 0 1.5px ' + T.gold, marginBottom: 14 }}>
            <Icon name="speaker" size={26} color={T.gold} stroke={1.8} /></div>
          <Eyebrow color={T.goldDim}>왜 이 목소리인가요?</Eyebrow>
          <h3 style={{ fontFamily: T.display, fontSize: 23, letterSpacing: -.5, color: T.ink, margin: '8px 0 6px' }}>
            {v.name} · {v.role}</h3>
          <div style={{ fontFamily: T.sans, fontSize: 13.5, color: T.muted, marginBottom: 12 }}>{v.tone}</div>
          <p style={{ fontFamily: T.sans, fontSize: 15, lineHeight: 1.65, color: T.body, margin: 0 }}>{v.why}</p>
          <div style={{ marginTop: 22 }}><Btn full kind="primary" onClick={onClose}>알겠어요</Btn></div>
        </div>
      </div>
    );
  }

  // ── Loading (anticipatory) ──────────────────────────────────
  function Loading({ go, app, params }) {
    const s = window.siteById(params.id) || window.SITES[0];
    const { v, it } = window.pickVoice(app);
    const lens = window.INTERESTS.find(i => i.id === it);
    const steps = [
      `${s.name}의 기록을 모으는 중`,
      `‘${lens ? lens.label : '관심사'}’ 관점으로 이야기를 엮는 중`,
      `${v.name}의 목소리를 준비하는 중`,
      '이야기가 곧 시작돼요',
    ];
    const [step, setStep] = useState(0);
    useEffect(() => {
      if (step >= steps.length - 1) { const t = setTimeout(() => go('player', { id: s.id }), 1100); return () => clearTimeout(t); }
      const t = setTimeout(() => setStep(step + 1), 1150);
      return () => clearTimeout(t);
    }, [step]);
    return (
      <div style={{ position: 'absolute', inset: 0, background: T.teal, overflow: 'hidden',
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 34px' }}>
        <div style={{ position: 'absolute', inset: 0, background:
          'radial-gradient(120% 70% at 50% 18%, rgba(198,154,62,.22), transparent 60%)' }} />
        {/* concentric rings */}
        <div style={{ position: 'relative', width: 150, height: 150, marginBottom: 40 }}>
          {[0, 1, 2].map(i => (
            <div key={i} style={{ position: 'absolute', inset: i * 18, borderRadius: 99,
              border: '1.5px solid ' + (i === 0 ? T.gold : 'rgba(232,210,154,' + (0.4 - i * 0.13) + ')'),
              animation: `munaBreath 2.6s ease-in-out ${i * 0.3}s infinite` }} />
          ))}
          <div style={{ position: 'absolute', inset: 54, borderRadius: 99, background: T.tealEl,
            display: 'grid', placeItems: 'center', boxShadow: 'inset 0 0 0 1.5px ' + T.gold }}>
            <Icon name="speaker" size={26} color={T.gold} stroke={1.7} />
          </div>
        </div>
        <Eyebrow color={T.gold} style={{ textAlign: 'center' }}>당신만의 이야기를 짓는 중</Eyebrow>
        <div style={{ height: 64, marginTop: 16, display: 'flex', alignItems: 'center' }}>
          <div key={step} style={{ fontFamily: T.display, fontSize: 22, letterSpacing: -.4, color: T.onDark,
            textAlign: 'center', lineHeight: 1.35, animation: 'munaFade .5s ease' }}>{steps[step]}</div>
        </div>
        <div style={{ display: 'flex', gap: 7, marginTop: 22 }}>
          {steps.map((_, i) => <div key={i} style={{ width: 7, height: 7, borderRadius: 9,
            background: i <= step ? T.gold : 'rgba(246,240,227,.22)', transition: 'all .4s' }} />)}
        </div>
      </div>
    );
  }

  Object.assign(window, { Detail, Loading });
})();
