const SERIES = [
  {
    id: 's1',
    num: '01',
    title: '思考の解剖',
    titleEn: 'Anatomy of Thought',
    desc: '日々の曖昧な感覚を、言葉のメスで切り分けていく連続エッセイ。自分でも気づかない前提や癖を、時間をかけて観察します。',
    count: 38,
    accent: '#B49AFF',
    pattern: 'lines'
  },
  {
    id: 's2',
    num: '02',
    title: 'コード手記',
    titleEn: 'Coding Diary',
    desc: '手元のエディタで起きた小さな発見を、他人に見せる前提で書き残すメモ集。設計判断、失敗、言語やツールへの偏愛について。',
    count: 47,
    accent: '#A78BFA',
    pattern: 'grid'
  },
  {
    id: 's3',
    num: '03',
    title: '夜想ノート',
    titleEn: 'Nocturne',
    desc: '眠れない夜の散歩中に考えたこと。都市の音、看板の灯り、誰でもない人の横顔。短い散文と写真のキャプションで構成される連作。',
    count: 29,
    accent: '#C4A7FF',
    pattern: 'dots'
  },
  {
    id: 's4',
    num: '04',
    title: '本の輪郭',
    titleEn: 'Silhouettes of Books',
    desc: '読み終えた本について、あらすじを語るのではなく、輪郭だけを残す書評の試み。線を引いた一文から、全体を推測する読書論。',
    count: 18,
    accent: '#9B7FFB',
    pattern: 'rule'
  },
  {
    id: 's5',
    num: '05',
    title: '旅の遠景',
    titleEn: 'Distant Landscapes',
    desc: '訪れた街の、観光ではない部分について。朝の商店街、終電後のホーム、地図に載らない道。距離を置いた視点で編む旅行記。',
    count: 10,
    accent: '#D4B8FF',
    pattern: 'wave'
  },
];

function Pattern({ kind, accent }){
  const common = { position:'absolute', inset:0, width:'100%', height:'100%', opacity: 0.9 };
  if (kind === 'lines') {
    return (
      <svg style={common} viewBox="0 0 400 260" preserveAspectRatio="none">
        <defs>
          <linearGradient id="lg1" x1="0" x2="1">
            <stop offset="0" stopColor={accent} stopOpacity="0.0"/>
            <stop offset="0.5" stopColor={accent} stopOpacity="0.9"/>
            <stop offset="1" stopColor={accent} stopOpacity="0.0"/>
          </linearGradient>
        </defs>
        {Array.from({length:22}).map((_,i)=>(
          <path key={i} d={`M 0 ${20+i*10} Q 200 ${20+i*10 + (i%2?-18:18)} 400 ${20+i*10}`}
            fill="none" stroke="url(#lg1)" strokeWidth="0.6" opacity={0.2 + (i%5)*0.1}/>
        ))}
      </svg>
    );
  }
  if (kind === 'grid') {
    return (
      <svg style={common} viewBox="0 0 400 260">
        <defs>
          <radialGradient id="rg1" cx="0.7" cy="0.3" r="0.8">
            <stop offset="0" stopColor={accent} stopOpacity="0.5"/>
            <stop offset="1" stopColor={accent} stopOpacity="0"/>
          </radialGradient>
        </defs>
        <rect width="400" height="260" fill="url(#rg1)"/>
        {Array.from({length:20}).map((_,i)=>(
          <line key={`v${i}`} x1={i*22} y1="0" x2={i*22} y2="260" stroke={accent} strokeOpacity="0.15" strokeWidth="0.6"/>
        ))}
        {Array.from({length:12}).map((_,i)=>(
          <line key={`h${i}`} x1="0" y1={i*22} x2="400" y2={i*22} stroke={accent} strokeOpacity="0.15" strokeWidth="0.6"/>
        ))}
        <rect x="242" y="108" width="22" height="22" fill="none" stroke={accent} strokeWidth="1.2"/>
      </svg>
    );
  }
  if (kind === 'dots') {
    return (
      <svg style={common} viewBox="0 0 400 260">
        {Array.from({length: 300}).map((_,i)=>{
          const x = (i*37) % 400;
          const y = Math.floor(i*37/400)*12 % 260;
          const r = 0.6 + ((i*13)%10)/14;
          const o = 0.1 + ((i*7)%10)/20;
          return <circle key={i} cx={x} cy={y} r={r} fill={accent} opacity={o}/>;
        })}
        <circle cx="300" cy="80" r="38" fill="none" stroke={accent} strokeOpacity="0.6"/>
        <circle cx="300" cy="80" r="2" fill={accent}/>
      </svg>
    );
  }
  if (kind === 'rule') {
    return (
      <svg style={common} viewBox="0 0 400 260">
        {Array.from({length:26}).map((_,i)=>{
          const y = i*10 + 5;
          const len = 40 + ((i*53)%320);
          const x = (i*29)%200;
          return <line key={i} x1={x} y1={y} x2={x+len} y2={y} stroke={accent} strokeOpacity={0.15 + (i%4)*0.1} strokeWidth="0.7"/>;
        })}
        <text x="40" y="140" fontFamily="Instrument Serif, serif" fontStyle="italic" fontSize="72" fill={accent} opacity="0.35">"</text>
      </svg>
    );
  }
  if (kind === 'wave') {
    return (
      <svg style={common} viewBox="0 0 400 260" preserveAspectRatio="none">
        {Array.from({length:16}).map((_,i)=>(
          <path key={i}
            d={`M 0 ${200-i*6} C 100 ${200-i*6 - 30} 200 ${200-i*6 + 30} 400 ${200-i*6}`}
            fill="none" stroke={accent} strokeOpacity={0.1+i*0.035} strokeWidth="0.7"/>
        ))}
      </svg>
    );
  }
  return null;
}

const seriesStyles = {
  outer: { position:'relative' },
  intro: { padding: '24px 0 20px' },
  eyebrow: {
    fontFamily:"'JetBrains Mono', monospace", fontSize: 11,
    letterSpacing: 2, color: '#B49AFF'
  },
  headerRow: { display:'flex', alignItems:'end', justifyContent:'space-between', gap: 24, marginTop: 10 },
  h2: {
    fontFamily: "'Instrument Serif', serif",
    fontSize: 'clamp(40px, 5vw, 64px)', margin: 0,
    letterSpacing: '-0.01em', lineHeight: 1,
  },
  sub: {
    color:'#A8A0BC', fontSize: 14, maxWidth: 440, lineHeight: 1.65, margin:0
  },
  hintRow: {
    display:'flex', alignItems:'center', gap: 10,
    marginTop: 28, color:'#6E6782', fontSize:12,
    fontFamily:"'JetBrains Mono', monospace", letterSpacing: 1
  },

  stage: (h)=>({ position:'relative', height: `${h}px` }),
  sticky: {
    position:'sticky', top: 0,
    height: '100vh', overflow:'hidden',
    display:'flex', alignItems:'center'
  },
  track: {
    display:'flex', gap: 32, paddingLeft: 'max(32px, calc((100vw - 1280px)/2 + 32px))', paddingRight: '20vw',
    willChange: 'transform'
  },

  card: (accent) => ({
    flex: '0 0 auto',
    width: 480, height: 560,
    borderRadius: 20,
    background: 'linear-gradient(180deg, rgba(29,23,41,0.8), rgba(18,16,28,0.9))',
    border: `1px solid ${accent}33`,
    position:'relative', overflow:'hidden',
    display:'flex', flexDirection:'column',
    transition: 'border-color .25s ease, transform .4s ease'
  }),
  preview: {
    position:'relative', height: 260,
    borderBottom: '1px solid rgba(42,34,56,0.8)',
    overflow:'hidden'
  },
  previewInner: {
    position:'absolute', inset: 0,
    background: 'linear-gradient(180deg, rgba(18,16,28,0.0) 40%, rgba(18,16,28,0.7) 100%)'
  },
  numBadge: {
    position:'absolute', top: 18, left: 22,
    fontFamily: "'JetBrains Mono', monospace",
    fontSize: 11, letterSpacing: 2, color:'#A8A0BC',
    border:'1px solid #2A2238', padding:'4px 8px', borderRadius: 999,
    background:'rgba(14,11,22,0.6)'
  },
  count: {
    position:'absolute', top: 18, right: 22,
    fontFamily:"'JetBrains Mono', monospace", fontSize: 11, color:'#A8A0BC',
  },

  body: { padding: 28, display:'flex', flexDirection:'column', flex:1, gap: 14 },
  titleEn: { fontFamily:"'JetBrains Mono', monospace", fontSize:11, letterSpacing:2, color:'#B49AFF' },
  title: { fontFamily:"'Instrument Serif', serif", fontSize: 38, lineHeight: 1.05, margin:0, letterSpacing:'-0.01em' },
  desc: { color:'#C8C0DC', fontSize: 14.5, lineHeight: 1.75, margin:0 },

  footer: {
    marginTop:'auto', paddingTop: 16,
    borderTop: '1px dashed rgba(42,34,56,0.9)',
    display:'flex', alignItems:'center', justifyContent:'space-between'
  },
  readBtn: {
    fontSize: 13, color:'#F5F1FF', fontWeight: 500,
    display:'inline-flex', alignItems:'center', gap: 8
  },
  updateTxt: {
    fontFamily:"'JetBrains Mono', monospace", fontSize: 11, color:'#6E6782'
  },

  progressWrap: {
    position:'absolute', bottom: 40, left: 0, right: 0,
    display:'flex', justifyContent:'center', pointerEvents:'none'
  },
  progressInner: {
    width: 'min(1280px, calc(100% - 64px))',
    display:'flex', alignItems:'center', gap: 16
  },
  rail: { flex:1, height: 2, background:'rgba(42,34,56,0.8)', borderRadius: 2, overflow:'hidden' },
  fill: (pct)=>({ height:'100%', width:`${pct*100}%`, background:'linear-gradient(90deg,#8B5CF6,#B49AFF)' }),
  pctLabel: { fontFamily:"'JetBrains Mono', monospace", fontSize: 11, color:'#A8A0BC', minWidth: 64, textAlign:'right' },
  arrows: { display:'flex', gap: 8, pointerEvents:'auto' },
  arrow: {
    width: 38, height: 38, borderRadius: 999,
    border:'1px solid #2A2238', background:'rgba(29,23,41,0.8)',
    display:'inline-flex', alignItems:'center', justifyContent:'center',
    color:'#C8C0DC', backdropFilter:'blur(10px)'
  }
};

function SeriesScroll(){
  const stageRef = React.useRef(null);
  const trackRef = React.useRef(null);
  const [progress, setProgress] = React.useState(0);
  const [trackWidth, setTrackWidth] = React.useState(0);
  const [vw, setVw] = React.useState(typeof window!=='undefined' ? window.innerWidth : 1440);

  React.useEffect(()=>{
    const measure = () => {
      if (!trackRef.current) return;
      const total = trackRef.current.scrollWidth;
      setTrackWidth(total);
      setVw(window.innerWidth);
    };
    measure();
    window.addEventListener('resize', measure);
    return ()=>window.removeEventListener('resize', measure);
  }, []);

  const travel = Math.max(0, trackWidth - vw + 120);
  const stageHeight = travel + (typeof window!=='undefined' ? window.innerHeight : 900);

  React.useEffect(()=>{
    const onScroll = () => {
      if (!stageRef.current) return;
      const rect = stageRef.current.getBoundingClientRect();
      const total = stageRef.current.offsetHeight - window.innerHeight;
      const scrolled = Math.min(Math.max(-rect.top, 0), total);
      const p = total > 0 ? scrolled / total : 0;
      setProgress(p);
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return ()=>window.removeEventListener('scroll', onScroll);
  }, [stageHeight]);

  const x = -progress * travel;

  const jumpBy = (dir) => {
    if (!stageRef.current) return;
    const total = stageRef.current.offsetHeight - window.innerHeight;
    const cardsVisible = Math.max(1, Math.floor(vw / 512));
    const step = total / (SERIES.length - cardsVisible + 1);
    const cur = window.scrollY;
    const rectTop = stageRef.current.getBoundingClientRect().top + window.scrollY;
    const targetWithin = Math.min(Math.max((cur - rectTop) + dir*step, 0), total);
    window.scrollTo({ top: rectTop + targetWithin, behavior: 'smooth' });
  };

  return (
    <section id="series" style={seriesStyles.outer}>
      <div className="inner" style={seriesStyles.intro}>
        <div style={seriesStyles.eyebrow}>§ 02 — ONGOING SERIES</div>
        <div style={seriesStyles.headerRow}>
          <h2 style={seriesStyles.h2}>連載<span style={{fontStyle:'italic', color:'#B49AFF'}}> / series</span></h2>
          <p style={seriesStyles.sub}>
            いくつかのテーマを、腰を据えて書き続けています。途中からでも、終わりからでも、どうぞ。
          </p>
        </div>
        <div style={seriesStyles.hintRow}>
          <span style={{width:24, height:1, background:'#B49AFF'}}/>
          SCROLL ↓ TO DRAG HORIZONTALLY →
        </div>
      </div>

      <div ref={stageRef} style={seriesStyles.stage(stageHeight)}>
        <div style={seriesStyles.sticky}>
          <div ref={trackRef} style={{ ...seriesStyles.track, transform: `translate3d(${x}px, 0, 0)` }}>
            {SERIES.map((s, idx)=>(
              <SeriesCard key={s.id} s={s} idx={idx} total={SERIES.length}/>
            ))}
            <EndCard/>
          </div>

          <div style={seriesStyles.progressWrap}>
            <div style={seriesStyles.progressInner}>
              <div style={seriesStyles.arrows}>
                <button style={seriesStyles.arrow} onClick={()=>jumpBy(-1)} aria-label="prev">‹</button>
                <button style={seriesStyles.arrow} onClick={()=>jumpBy(1)} aria-label="next">›</button>
              </div>
              <div style={seriesStyles.rail}>
                <div style={seriesStyles.fill(progress)}/>
              </div>
              <div style={seriesStyles.pctLabel}>
                {String(Math.round(progress*100)).padStart(3,'0')} / 100
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function SeriesCard({ s, idx, total }){
  const [hover, setHover] = React.useState(false);
  return (
    <article
      onMouseEnter={()=>setHover(true)}
      onMouseLeave={()=>setHover(false)}
      style={{
        ...seriesStyles.card(s.accent),
        borderColor: hover ? `${s.accent}88` : `${s.accent}33`,
        transform: hover ? 'translateY(-4px)' : 'translateY(0)',
        boxShadow: hover ? `0 40px 80px -40px ${s.accent}55, inset 0 0 0 1px ${s.accent}22` : 'none'
      }}
    >
      <div style={{...seriesStyles.preview, background: `linear-gradient(140deg, ${s.accent}10, transparent 60%), radial-gradient(circle at 30% 20%, ${s.accent}22, transparent 60%)`}}>
        <Pattern kind={s.pattern} accent={s.accent}/>
        <div style={seriesStyles.previewInner}/>
        <div style={seriesStyles.numBadge}>SERIES · {s.num} / {String(total).padStart(2,'0')}</div>
        <div style={seriesStyles.count}>{s.count} entries</div>
      </div>
      <div style={seriesStyles.body}>
        <div style={seriesStyles.titleEn}>— {s.titleEn}</div>
        <h3 style={seriesStyles.title}>{s.title}</h3>
        <p style={seriesStyles.desc}>{s.desc}</p>
        <div style={seriesStyles.footer}>
          <a href="#" style={seriesStyles.readBtn}>
            Enter series
            <span style={{
              display:'inline-flex', alignItems:'center', justifyContent:'center',
              width: 26, height: 26, borderRadius: 999,
              background: hover ? s.accent : 'rgba(139,92,246,0.15)',
              color: hover ? '#14111C' : '#F5F1FF',
              transition:'all .2s ease'
            }}>→</span>
          </a>
          <span style={seriesStyles.updateTxt}>UPDATED · 2026.04.{10 + idx*2}</span>
        </div>
      </div>
    </article>
  );
}

function EndCard(){
  return (
    <article style={{
      flex: '0 0 auto', width: 360, height: 560,
      borderRadius: 20, border:'1px dashed #2A2238',
      display:'flex', flexDirection:'column', justifyContent:'center', alignItems:'center',
      padding: 40, textAlign:'center', color:'#A8A0BC'
    }}>
      <div style={{
        width: 56, height: 56, borderRadius:999, border:'1px solid #2A2238',
        display:'flex', alignItems:'center', justifyContent:'center', marginBottom: 20,
        color:'#B49AFF', fontFamily:"'Instrument Serif', serif", fontStyle:'italic', fontSize: 24
      }}>∎</div>
      <div style={{fontFamily:"'Instrument Serif', serif", fontSize: 28, color:'#F5F1FF', lineHeight:1.2}}>
        これ以上は<br/>まだ書いていません
      </div>
      <div style={{fontFamily:"'JetBrains Mono', monospace", fontSize: 11, color:'#6E6782', marginTop: 18, letterSpacing:1.5}}>
        NEW SERIES · COMING 2026 Q3
      </div>
    </article>
  );
}

window.SeriesScroll = SeriesScroll;
