// Shared primitives used across LUCE pages
const { useState, useEffect, useRef, useMemo, useCallback, Fragment } = React;

// ------- Intersection reveal hook -------
function useReveal(threshold = 0.15) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) { setShown(true); io.disconnect(); }
      });
    }, { threshold });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, shown];
}

// ------- Reveal wrapper -------
function Reveal({ children, delay = 0, slow = false, as: Tag = 'div', className = '', ...rest }) {
  const [ref, shown] = useReveal();
  return (
    <Tag
      ref={ref}
      className={`reveal ${slow ? 'reveal-slow' : ''} ${shown ? 'in' : ''} ${className}`}
      style={{ transitionDelay: `${delay}ms` }}
      {...rest}
    >
      {children}
    </Tag>
  );
}

// ------- Character split reveal -------
function CharSplit({ text, delay = 0, className = '', italic = false }) {
  const [ref, shown] = useReveal();
  const chars = useMemo(() => Array.from(text), [text]);
  return (
    <span ref={ref} className={`char-split ${shown ? 'in' : ''} ${className}`}>
      {chars.map((c, i) => (
        <span key={i} style={{ transitionDelay: `${delay + i * 28}ms`, fontStyle: italic ? 'italic' : undefined }}>
          {c === ' ' ? '\u00A0' : c}
        </span>
      ))}
    </span>
  );
}

// ------- Particle Canvas (React wrapper) -------
function ParticleCanvas({ opts = {}, className = '', style = {} }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!ref.current || !window.LuceParticles) return;
    const pf = new window.LuceParticles(ref.current, opts);
    return () => pf.destroy();
  }, [JSON.stringify(opts)]);
  return <canvas ref={ref} className={`particle-canvas ${className}`} style={style} />;
}

// ------- Nav -------
const PAGES = [
  { id: 'home', label: 'Home', jp: 'トップ' },
  { id: 'treatments', label: 'Treatments', jp: '施術' },
  { id: 'doctor', label: 'Doctor', jp: '医師' },
  { id: 'platinum', label: 'Platinum', jp: '会員' },
  { id: 'interior', label: 'Interior', jp: '内観' },
  { id: 'journal', label: 'Journal', jp: 'ジャーナル' },
  { id: 'faq', label: 'FAQ', jp: 'Q&A' },
  { id: 'reserve', label: 'Reserve', jp: '予約' },
];

function Nav({ page, setPage, dark = false }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 40);
    on();
    window.addEventListener('scroll', on);
    return () => window.removeEventListener('scroll', on);
  }, []);
  return (
    <header className={`nav ${scrolled ? 'scrolled' : ''} ${dark ? 'dark' : ''}`}>
      <a href="#home" onClick={(e)=>{e.preventDefault(); setPage('home');}} className="nav-logo">
        LUCE
        <small>CLINIC&nbsp;·&nbsp;OMOTESANDŌ</small>
      </a>
      <nav className="nav-center">
        {PAGES.filter(p => !['reserve'].includes(p.id)).map(p => (
          <a key={p.id} href={`#${p.id}`}
             className={page === p.id ? 'active' : ''}
             onClick={(e)=>{e.preventDefault(); setPage(p.id);}}>
            {p.label}
          </a>
        ))}
      </nav>
      <div className="nav-right">
        <div className="nav-lang"><b>JP</b>&nbsp;/&nbsp;EN</div>
        <a href="#reserve" onClick={(e)=>{e.preventDefault(); setPage('reserve');}} className="nav-cta">
          <span>Reserve</span>
        </a>
      </div>
    </header>
  );
}

// ------- Footer -------
function Footer({ setPage }) {
  return (
    <footer className="footer">
      <div className="footer-particles" style={{position:'absolute',inset:0,opacity:0.4}}>
        <ParticleCanvas opts={{ density: 0.00008, color: '230, 201, 184', color2: '239, 217, 204', opacity: 0.6 }} />
      </div>
      <div style={{position:'relative', zIndex:2}}>
        <div className="footer-inner">
          <div>
            <div className="footer-logo">L<em>U</em>CE</div>
            <div className="footer-tag">Be your own light.</div>
            <p style={{marginTop:40, opacity:0.6, fontFamily:'var(--serif-jp)', fontSize:13, lineHeight:2, maxWidth:360}}>
              完全個室・女性医師による最先端の美容医療。<br/>
              表参道・骨董通りの静かな一角で、あなた自身の光を取り戻す時間を。
            </p>
          </div>
          <div>
            <h4>Clinic</h4>
            <ul>
              <li><a onClick={()=>setPage('treatments')}>施術一覧</a></li>
              <li><a onClick={()=>setPage('doctor')}>医師紹介</a></li>
              <li><a onClick={()=>setPage('interior')}>内観</a></li>
              <li><a onClick={()=>setPage('platinum')}>プラチナ会員</a></li>
            </ul>
          </div>
          <div>
            <h4>Support</h4>
            <ul>
              <li><a onClick={()=>setPage('faq')}>よくあるご質問</a></li>
              <li><a onClick={()=>setPage('journal')}>ジャーナル</a></li>
              <li><a onClick={()=>setPage('reserve')}>ご予約</a></li>
              <li><a>お問い合わせ</a></li>
            </ul>
          </div>
          <div>
            <h4>Contact</h4>
            <ul style={{opacity:0.85}}>
              <li>東京都港区南青山5-x-x</li>
              <li>骨董通り THE TERRACE 4F</li>
              <li>03-xxxx-xxxx</li>
              <li>11:00 — 20:00 / 水曜休</li>
            </ul>
          </div>
        </div>
        <div className="footer-bot">
          <div>© 2026 LUCE Clinic. All rights reserved.</div>
          <div>Privacy&nbsp;·&nbsp;Terms&nbsp;·&nbsp;Medical Policy</div>
        </div>
      </div>
    </footer>
  );
}

// ------- Photo placeholder (editorial quality) -------
// Generates a CSS-gradient-driven "photographic" block with treatment.
function Photo({ kind = 'face', ratio = '3/4', className = '', style = {}, children }) {
  const bgs = {
    face: `radial-gradient(ellipse at 60% 35%, rgba(255, 220, 200, 0.9) 0%, rgba(230, 201, 184, 0.6) 30%, rgba(180, 140, 120, 0.4) 60%, rgba(40, 30, 26, 0.8) 100%)`,
    profile: `radial-gradient(ellipse at 40% 30%, rgba(255, 230, 215, 0.85), rgba(220, 185, 168, 0.6) 40%, rgba(80, 55, 45, 0.7) 80%)`,
    hands: `radial-gradient(circle at 50% 60%, rgba(240, 215, 200, 0.9), rgba(200, 165, 150, 0.5) 50%, rgba(20, 16, 14, 0.7) 100%)`,
    interior: `linear-gradient(135deg, rgba(250, 246, 241, 0.95), rgba(230, 201, 184, 0.4) 50%, rgba(14, 14, 14, 0.6) 100%)`,
    interior2: `linear-gradient(160deg, rgba(240, 230, 220, 0.8) 0%, rgba(14, 14, 14, 0.75) 80%)`,
    dark: `radial-gradient(circle at 70% 30%, rgba(180, 140, 118, 0.5), rgba(14, 14, 14, 1) 70%)`,
    gold: `linear-gradient(135deg, rgba(230, 201, 184, 0.9), rgba(184, 153, 104, 0.6) 40%, rgba(50, 40, 32, 0.9) 100%)`,
    serum: `radial-gradient(ellipse at 50% 40%, rgba(255, 240, 225, 0.95), rgba(230, 201, 184, 0.55) 40%, rgba(120, 92, 78, 0.6) 90%)`,
    orchid: `radial-gradient(ellipse at 30% 70%, rgba(239, 217, 204, 0.85), rgba(212, 168, 150, 0.4) 50%, rgba(14, 14, 14, 0.85) 95%)`,
    marble: `linear-gradient(170deg, rgba(250, 246, 241, 1) 0%, rgba(239, 231, 220, 1) 40%, rgba(212, 195, 178, 0.7) 100%)`,
    mist: `linear-gradient(200deg, rgba(250, 246, 241, 0.95), rgba(230, 201, 184, 0.6) 50%, rgba(180, 140, 120, 0.5) 100%)`,
  };
  return (
    <div className={`photo ${className}`} style={{
      aspectRatio: ratio,
      background: bgs[kind] || bgs.face,
      position: 'relative',
      overflow: 'hidden',
      ...style
    }}>
      <div style={{
        position:'absolute', inset:0,
        background: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.08 0 0 0 0 0.06 0 0 0 0.4 0'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.5'/></svg>")`,
        mixBlendMode: 'overlay',
        opacity: 0.55
      }}/>
      <div style={{
        position:'absolute', inset:0,
        background: 'linear-gradient(180deg, transparent 60%, rgba(14,14,14,0.35) 100%)'
      }}/>
      {children}
    </div>
  );
}

// ------- Number counter for index pills -------
function Idx({ n }) {
  const s = String(n).padStart(2, '0');
  return <span className="mono" style={{color:'var(--stone)', fontSize:11, letterSpacing:'0.3em'}}>{s}</span>;
}

window.Nav = Nav;
window.Footer = Footer;
window.Reveal = Reveal;
window.CharSplit = CharSplit;
window.ParticleCanvas = ParticleCanvas;
window.Photo = Photo;
window.Idx = Idx;
window.useReveal = useReveal;
window.PAGES = PAGES;
