// Guide — main content: chapters (tracks), drum of tips, mascot dialogues
const { useState: useStateG, useEffect: useEffectG, useRef: useRefG } = React;

const CHAPTERS = [
  {
    num: "01",
    title: "убей алгоритм в себе",
    side: "A",
    duration: "4:13",
    body: "tiktok, reels, discover weekly — это не твой вкус. это среднее арифметическое двух миллиардов людей. первое упражнение — неделю слушать только то, что тебе прислал друг. не алгоритм. друг. если друзей с музыкой нет — найди одного. это важнее, чем найти парня/девушку.",
    rule: "правило: если трек вышел в рекомендациях у трёх разных людей — он мёртв.",
    dialogue: {
      madk1d: "брат, я тут новый альбом нашёл",
      prince: "spotify радио подкинул?",
      madk1d: "не, парень из автосервиса дал флешку",
      prince: "читаю тебя. продолжай.",
    },
  },
  {
    num: "02",
    title: "молчи о том, что слушаешь",
    side: "A",
    duration: "3:47",
    body: "нишевый никогда не выкладывает now playing. не пишет обзоры в stories. не делает фото с концерта. если кто-то спросит — отвечай уклончиво или назови один трек. пусть копают сами. объяснить — значит обесценить. твой плейлист — это исповедь, а не афиша.",
    rule: "правило: слушают все — знают единицы.",
    dialogue: {
      madk1d: "а если спросят?",
      prince: "говори «забыл». это всегда правда и неправда одновременно.",
      madk1d: "а если свой трек спросят скинуть",
      prince: "скидываешь другой. но хороший. пусть верят.",
    },
  },
  {
    num: "03",
    title: "одежда как документ",
    side: "A",
    duration: "5:02",
    body: "твои вещи должны нельзя нагуглить по маркетплейсу. секонд, дроп-шоп, пошив, чужой шкаф — да. zara, h&m, reserved — терминальная стадия нормиса. чёрное не обязательно, но помогает. цвет в одежде — это всегда заявление. если ты не готов к заявлению — носи чёрное.",
    rule: "правило: вещь без истории — вещь без ценности.",
    dialogue: {
      madk1d: "а кроссы новые где брать?",
      prince: "у старшего брата, который уехал в берлин",
      madk1d: "у меня нет старшего брата",
      prince: "придумай.",
    },
  },
  {
    num: "04",
    title: "интернет — телега, а не тикток",
    side: "B",
    duration: "4:44",
    body: "главная платформа нишевого — закрытый канал на 800 человек, куда ты попал по приглашению. там не лайки, там — сообщения. никаких shorts. никаких клиповых мыслей. читай. пиши длинно. если писать нечего — молчи. молчание важнее любого поста.",
    rule: "правило: чем меньше подписчиков у канала — тем ценнее контент.",
    dialogue: {
      madk1d: "а reels? я там смеюсь",
      prince: "смех дешевеет, если его много. смотри реже. цени.",
      madk1d: "ты душный",
      prince: "я прав.",
    },
  },
  {
    num: "05",
    title: "не будь ироничным ко всему",
    side: "B",
    duration: "3:28",
    body: "ирония — броня нормиса. защита от того, чтобы быть пойманным на настоящем чувстве. нишевый умеет быть серьёзным. плакать под трек и не скриншотить. сидеть в тишине и не снимать сторис. любить вещи — открыто. цинизм — это последнее прибежище тех, у кого не было своего.",
    rule: "правило: если ты всё превращаешь в мем — ты уже мем.",
    dialogue: {
      madk1d: "то есть, без шуток вообще?",
      prince: "шути о других. серьёзен — о своём.",
      madk1d: "а про себя когда стебаться",
      prince: "когда никто не видит.",
    },
  },
  {
    num: "06",
    title: "один старый город",
    side: "B",
    duration: "6:66",
    body: "у каждого нишевого есть один город, в котором он был один раз и теперь всегда говорит «в москве / питере / тбилиси совсем другое». это не понты. это привязка. ты не обязан там жить. ты обязан туда иногда возвращаться, даже мысленно. у нормиса нет города. у нормиса есть аэропорты.",
    rule: "правило: география — это вкус. без неё ты нигде.",
    dialogue: {
      madk1d: "я был только в турции all inclusive",
      prince: "начни с малого. съезди в тверь зимой.",
      madk1d: "зачем",
      prince: "потом поймёшь.",
    },
  },
];

const TIPS = [
  "удали tiktok. нет — правда удали. сейчас.",
  "перестань ставить лайки. пусть все думают, что ты не видел.",
  "выключи автопродление spotify premium. слушай с паузами.",
  "купи что-нибудь физическое. кассету, виниl, журнал. трогай.",
  "не проси плейлист. дай свой. без объяснений.",
  "перестань использовать слово «кринж». оно кринж.",
  "один день в неделю — без интернета вообще. страшно — значит нужно.",
  "не фотографируй еду. ешь.",
  "если все вокруг смеются над шуткой — промолчи. шутка мёртвая.",
  "пиши длинные сообщения. голосовые — это лень.",
  "запомни 3 альбома до 2010 года, которые никто не знает. это твой паспорт.",
  "не объясняй свой ник. пусть спрашивают.",
  "перестань заканчивать сообщения скобкой).",
  "если тебя не понимают — хорошо. ты не для всех.",
  "нишевость не в том, чтобы быть лучше. в том, чтобы быть собой без аудитории.",
];

function Guide({ score, onSecret }) {
  return (
    <div className="screen" style={{ padding: '120px 0 120px', position: 'relative', paddingLeft: 0, paddingRight: 0 }}>
      {/* Background photo — fixed, visible, subtle purple tint */}
      <div style={{
        position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none',
        backgroundImage: 'url(assets/doctrine-bg.png)',
        backgroundSize: 'cover',
        backgroundPosition: 'center',
        backgroundRepeat: 'no-repeat',
        filter: 'contrast(1.05) brightness(0.85)',
        opacity: 0.9,
      }} />
      {/* Subtle purple tint layer — doesn't kill the image */}
      <div style={{
        position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none',
        background: 'linear-gradient(180deg, rgba(26,11,46,0.35) 0%, rgba(10,5,18,0.55) 100%)',
      }} />
      {/* Bottom gradient for text readability */}
      <div style={{
        position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none',
        background: 'radial-gradient(ellipse at center, transparent 30%, rgba(7,5,12,0.55) 100%)',
      }} />

      <CrossesBg count={20} seed={999} />

      <div style={{ position: 'relative', zIndex: 1 }}>
        <GuideHeader score={score} />

        <div style={{ maxWidth: 1100, margin: '0 auto', padding: '0 clamp(16px, 4vw, 40px)' }}>
          {CHAPTERS.map((ch, i) => (
            <Chapter key={ch.num} ch={ch} i={i} />
          ))}

          <TipsDrum />

          <Outro onSecret={onSecret} />
        </div>
      </div>
    </div>
  );
}

function GuideHeader({ score }) {
  return (
    <div style={{
      maxWidth: 1100, margin: '0 auto 80px', padding: 'clamp(20px, 4vw, 40px)',
      position: 'relative', zIndex: 2,
      background: 'rgba(7,5,12,0.72)',
      backdropFilter: 'blur(6px)',
      WebkitBackdropFilter: 'blur(6px)',
      border: '1px solid rgba(201,168,255,0.1)',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between',
        alignItems: 'flex-end', borderBottom: '1px solid var(--lavender-dim)',
        paddingBottom: 20, marginBottom: 40,
        flexWrap: 'wrap', gap: 20,
      }}>
        <div>
          <div className="mono" style={{ color: 'var(--ash)', marginBottom: 10 }}>
            ДОКТРИНА · LP · 2026
          </div>
          <h1 style={{
            fontFamily: 'var(--f-gothic)',
            color: 'var(--lavender)',
            fontSize: 'clamp(60px, 10vw, 160px)',
            lineHeight: 0.9,
            textShadow: '0 0 40px rgba(201,168,255,0.3)',
          }}>
            евангелие <br />
            <span style={{ color: 'var(--blood)' }}>нишевого</span>
          </h1>
        </div>
        <div style={{ textAlign: 'right', fontFamily: 'var(--f-mono)', fontSize: 11, color: 'var(--ash)' }}>
          <div>A-SIDE / B-SIDE</div>
          <div>06 TRACKS · 28:20</div>
          <div style={{ color: 'var(--lavender)', marginTop: 6 }}>YOU: {score}% НИШЕВЫЙ</div>
        </div>
      </div>

      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))',
        gap: 40,
        fontFamily: 'var(--f-serif)', fontSize: 'clamp(16px, 2.2vw, 22px)', lineHeight: 1.6,
        color: 'var(--bone)',
      }}>
        <div>
          <div className="mono" style={{ color: 'var(--lavender)', marginBottom: 12 }}>
            СТОРОНА A — КАК ВЫЙТИ
          </div>
          шесть треков. читай по порядку. не скипай. у каждого — правило, диалог маскотов и одно упражнение на неделю.
        </div>
        <div>
          <div className="mono" style={{ color: 'var(--blood)', marginBottom: 12 }}>
            ВНИМАНИЕ
          </div>
          это не инструкция к тому, чтобы казаться крутым. это памятка о том, как не раствориться в общем шуме. разница — критическая.
        </div>
      </div>
    </div>
  );
}

function Chapter({ ch, i }) {
  const ref = useRefG(null);
  const [visible, setVisible] = useStateG(false);
  useEffectG(() => {
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) setVisible(true);
    }, { threshold: 0.15 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, []);

  const isB = ch.side === 'B';

  return (
    <div ref={ref} style={{
      margin: '100px 0',
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0)' : 'translateY(40px)',
      transition: 'opacity 0.8s, transform 0.8s',
      position: 'relative',
      background: 'rgba(7,5,12,0.78)',
      backdropFilter: 'blur(6px)',
      WebkitBackdropFilter: 'blur(6px)',
      border: '1px solid rgba(201,168,255,0.1)',
      padding: 'clamp(20px, 4vw, 40px)',
    }}>
      {/* track meta row */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 20,
        borderTop: '1px solid var(--lavender-dim)',
        borderBottom: '1px solid rgba(201,168,255,0.1)',
        padding: '16px 0', marginBottom: 40,
        fontFamily: 'var(--f-mono)', fontSize: 11, letterSpacing: '0.2em',
        textTransform: 'uppercase', color: 'var(--ash)',
      }}>
        <span style={{ color: 'var(--lavender)', fontSize: 22, fontFamily: 'var(--f-gothic)', fontWeight: 300 }}>
          {ch.num}
        </span>
        <span>SIDE {ch.side}</span>
        <span style={{ flex: 1 }}></span>
        <span>{ch.duration}</span>
        <span style={{ color: 'var(--blood)' }}>● PLAY</span>
      </div>

      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
        gap: 40,
        alignItems: 'start',
      }}>
        <div>
          <h2 style={{
            color: isB ? 'var(--blood)' : 'var(--lavender)',
            marginBottom: 24,
            textShadow: `0 0 30px ${isB ? 'rgba(220,60,60,0.3)' : 'rgba(201,168,255,0.3)'}`,
            textWrap: 'balance',
          }}>
            {ch.title}
          </h2>

          <p style={{
            fontFamily: 'var(--f-serif)',
            fontSize: 'clamp(16px, 2.2vw, 22px)',
            lineHeight: 1.6,
            color: 'var(--bone)',
            marginBottom: 28,
            textWrap: 'pretty',
          }}>
            {ch.body}
          </p>

          <div style={{
            borderLeft: `3px solid ${isB ? 'var(--blood)' : 'var(--lavender)'}`,
            paddingLeft: 20,
            fontFamily: 'var(--f-mono)',
            fontSize: 14,
            letterSpacing: '0.05em',
            color: isB ? 'var(--blood)' : 'var(--lavender)',
            textTransform: 'uppercase',
          }}>
            {ch.rule}
          </div>
        </div>

        <Dialogue d={ch.dialogue} />
      </div>
    </div>
  );
}

function Dialogue({ d }) {
  const lines = [
    { who: 'madk1d', text: d.madk1d, img: 'assets/madk1d.jpg', accent: 'var(--lavender)' },
    { who: 'тёмный принц', text: d.prince, img: 'assets/prince.jpg', accent: 'var(--blood)' },
    { who: 'madk1d', text: d.madk1d_2 || d.madk1d, img: 'assets/madk1d.jpg', accent: 'var(--lavender)' },
    { who: 'тёмный принц', text: d.prince_2 || d.prince, img: 'assets/prince.jpg', accent: 'var(--blood)' },
  ];
  // take only as many as exist
  const pairs = [
    ['madk1d', d.madk1d, 'assets/madk1d.jpg', 'var(--lavender)'],
    ['тёмный принц', d.prince, 'assets/prince.jpg', 'var(--blood)'],
  ];

  return (
    <div style={{
      background: 'linear-gradient(180deg, rgba(26,11,46,0.7), rgba(10,5,18,0.7))',
      border: '1px solid rgba(201,168,255,0.15)',
      padding: 24,
      position: 'relative',
    }}>
      <div className="mono" style={{
        position: 'absolute', top: -10, left: 20,
        background: 'var(--void)', padding: '0 10px',
        color: 'var(--ash)', fontSize: 10,
      }}>
        — диалог о треке —
      </div>

      <DialogueLine who="madk1d" text={d.madk1d} img="assets/madk1d.jpg" accent="var(--lavender)" />
      <DialogueLine who="тёмный принц" text={d.prince} img="assets/prince.jpg" accent="var(--blood)" right />
    </div>
  );
}

function DialogueLine({ who, text, img, accent, right }) {
  return (
    <div style={{
      display: 'flex',
      flexDirection: right ? 'row-reverse' : 'row',
      gap: 14,
      marginBottom: 18,
      alignItems: 'flex-start',
    }}>
      <div style={{
        width: 48, height: 48, flexShrink: 0,
        backgroundImage: `url(${img})`,
        backgroundSize: 'cover', backgroundPosition: 'center top',
        border: `1px solid ${accent}`,
        filter: 'contrast(1.1)',
      }} />
      <div style={{ flex: 1, textAlign: right ? 'right' : 'left' }}>
        <div className="mono" style={{ color: accent, fontSize: 10, marginBottom: 4 }}>
          {who}
        </div>
        <div style={{
          fontFamily: 'var(--f-serif)', fontSize: 18, fontStyle: 'italic',
          color: 'var(--bone)', lineHeight: 1.4,
        }}>
          — {text}
        </div>
      </div>
    </div>
  );
}

function TipsDrum() {
  const [idx, setIdx] = useStateG(0);
  const [spinning, setSpinning] = useStateG(false);

  const spin = () => {
    if (spinning) return;
    setSpinning(true);
    TP_Audio.playCrackle();
    let ticks = 0;
    const total = 12 + Math.floor(Math.random() * 8);
    const tick = () => {
      ticks++;
      setIdx((idx + ticks) % TIPS.length);
      TP_Audio.playClick();
      if (ticks < total) {
        setTimeout(tick, 60 + ticks * 8);
      } else {
        TP_Audio.play808(55, 0.6, 0.3);
        setSpinning(false);
      }
    };
    tick();
  };

  return (
    <div style={{
      margin: '140px 0 100px',
      border: '1px solid var(--lavender-dim)',
      padding: 'clamp(24px, 5vw, 50px)',
      position: 'relative',
      background: 'rgba(7,5,12,0.82)',
      backdropFilter: 'blur(6px)',
      WebkitBackdropFilter: 'blur(6px)',
    }}>
      <div className="mono" style={{
        position: 'absolute', top: -10, left: 30,
        background: 'var(--void)', padding: '0 12px',
        color: 'var(--blood)', fontSize: 11,
      }}>
        {'✟︎'} БАРАБАН ЗАПОВЕДЕЙ {'✟︎'}
      </div>

      <div style={{ textAlign: 'center', marginBottom: 30 }}>
        <div className="mono" style={{ color: 'var(--ash)', marginBottom: 12 }}>
          RULE {String(idx + 1).padStart(2, '0')} / {TIPS.length}
        </div>
        <div style={{
          fontFamily: 'var(--f-gothic)',
          fontWeight: 300,
          fontSize: 'clamp(28px, 4.5vw, 56px)',
          color: 'var(--bone)',
          lineHeight: 1.15,
          minHeight: 140,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          padding: '0 20px',
          transition: spinning ? 'none' : 'opacity 0.3s',
          filter: spinning ? 'blur(1px)' : 'none',
          textWrap: 'balance',
        }}>
          <span className="cross-text" style={{ color: 'var(--lavender)', marginRight: 14 }}>{'†︎'}</span>
          {TIPS[idx]}
          <span className="cross-text" style={{ color: 'var(--lavender)', marginLeft: 14 }}>{'†︎'}</span>
        </div>
      </div>

      <div style={{ textAlign: 'center' }}>
        <button className="btn" onClick={spin} disabled={spinning}>
          {spinning ? 'вращение...' : 'крутить барабан'}
        </button>
      </div>
    </div>
  );
}

function Outro({ onSecret }) {
  const [clicks, setClicks] = useStateG(0);
  const [hinted, setHinted] = useStateG(false);

  const onCross = () => {
    const next = clicks + 1;
    setClicks(next);
    TP_Audio.play808(40 + next * 8, 0.3, 0.3);
    if (next === 3 && !hinted) setHinted(true);
    if (next >= 7) {
      TP_Audio.playCrackle();
      setTimeout(onSecret, 300);
    }
  };

  return (
    <div style={{
      margin: '120px 0 40px',
      textAlign: 'center',
      padding: 'clamp(48px, 8vw, 80px) clamp(20px, 4vw, 40px)',
      borderTop: '1px solid var(--lavender-dim)',
      background: 'rgba(7,5,12,0.72)',
      backdropFilter: 'blur(6px)',
      WebkitBackdropFilter: 'blur(6px)',
    }}>
      <div className="mono" style={{ color: 'var(--ash)', marginBottom: 20 }}>
        END OF SIDE B
      </div>
      <h2 className="glitch fraktur" data-text="amen" style={{
        color: 'var(--bone)', fontSize: 'clamp(80px, 14vw, 220px)',
      }}>
        amen
      </h2>
      <div style={{
        fontFamily: 'var(--f-serif)', fontStyle: 'italic',
        fontSize: 22, color: 'var(--ash)', marginTop: 20,
        maxWidth: 560, margin: '20 auto 0',
      }}>
        дальше ты знаешь. нишевый не ищет — он позволяет найти себя.
      </div>

      <div style={{
        maxWidth: 560,
        margin: '60px auto 0',
        padding: 'clamp(24px, 4vw, 36px) clamp(20px, 4vw, 40px)',
        border: '1px solid var(--blood)',
        background: 'linear-gradient(180deg, rgba(26,11,46,0.5), rgba(10,5,18,0.5))',
        position: 'relative',
      }}>
        <div className="mono" style={{
          position: 'absolute', top: -9, left: '50%', transform: 'translateX(-50%)',
          background: 'var(--void)', padding: '0 14px',
          color: 'var(--blood)', fontSize: 10, whiteSpace: 'nowrap',
        }}>
          <span className="cross-text">{'✟︎'}</span> СЛЕДУЮЩАЯ СТОРОНА <span className="cross-text">{'✟︎'}</span>
        </div>
        <div style={{
          fontFamily: 'var(--f-serif)', fontStyle: 'italic',
          fontSize: 'clamp(18px, 2.2vw, 22px)', lineHeight: 1.5,
          color: 'var(--bone)', marginBottom: 24, marginTop: 6,
        }}>
          доктрина не кончается здесь. она продолжается там,
          где её не найдёт алгоритм.
        </div>
        <a
          href="https://t.me/+bQpSW8h0waM5YzIy"
          target="_blank"
          rel="noopener noreferrer"
          className="btn blood"
          onClick={() => { TP_Audio.play808(40, 0.5, 0.3); TP_Audio.playCrackle(); }}
        >
          войти в канал →
        </a>
        <div className="mono" style={{
          color: 'var(--ash)', fontSize: 10, marginTop: 16, opacity: 0.7,
        }}>
          телеграм · по приглашению · познать нишевость
        </div>
      </div>

      <div style={{ marginTop: 80, fontSize: 36, color: 'var(--lavender-dim)' }}>
        <span
          onClick={onCross}
          style={{
            cursor: 'none', padding: '0 4px',
            transition: 'all 0.2s',
            color: clicks > 0 ? 'var(--lavender)' : 'var(--lavender-dim)',
            textShadow: clicks > 3 ? '0 0 20px var(--lavender)' : 'none',
            display: 'inline-block',
            transform: `rotate(${clicks * 12}deg)`,
          }}
        >{'✟︎'}</span>
      </div>
      {hinted && (
        <div className="mono" style={{ color: 'var(--blood)', fontSize: 10, marginTop: 10, opacity: 0.6 }}>
          ...продолжай нажимать.
        </div>
      )}
    </div>
  );
}

window.Guide = Guide;
