/* =====================================================================
   SajuModule.jsx — 사주 전체 플로우 (천기문급 프리미엄 결과창)
   ① 헤더 → ② 무료 요약 해몽 → ③ Oriental Mystic Fantasy 캔버스
   → ④ 프리미엄 게이트 → ⑤ 폼/광고 →
   [A] 만세력 → [B] 오행분포(도넛+바) → [C] 3개월흐름도 →
   [D] 운세게이지 → [E] 카테고리리포트(border-l-4 amber) → [F] 부적액자
===================================================================== */
const _S = React;
const { useState, useEffect, useRef, useMemo } = _S;

/* ────────────────────────────────────────────────────────────────────
   1. SajuFreeDreamArt — Oriental Mystic Fantasy 캔버스 (잠금 없음)
───────────────────────────────────────────────────────────────────── */
function SajuFreeDreamArt({ url, lang }) {
  const L = LANG[lang];
  return (
    <div style={{ marginBottom:'32px' }}>
      <div style={{ textAlign:'center', marginBottom:'14px',
        color:'#fde68a', fontSize:'.72rem', fontWeight:700,
        letterSpacing:'.22em', textTransform:'uppercase',
        textShadow:'0 0 18px rgba(245,158,11,.55)' }}>
        {L.freeCanvasTitle}
      </div>
      <div style={{
        position:'relative', width:'100%', aspectRatio:'16/9',
        borderRadius:'14px', overflow:'hidden',
        background:'linear-gradient(135deg,#0a0400,#1a0800)',
        boxShadow:'0 0 0 1px rgba(255,255,255,.06),0 8px 48px rgba(0,0,0,.85),0 0 80px rgba(245,158,11,.14)'
      }}>
        {/* shimmer — <img> 뒤에서 로딩 중 배경 역할 */}
        <div style={{
          position:'absolute', inset:0, zIndex:1,
          background:'linear-gradient(90deg,#0a0400 25%,#1a0800 50%,#0a0400 75%)',
          backgroundSize:'200% 100%', animation:'shimmerLoad 1.6s infinite'
        }}/>
        {/* ★ freeDreamImageUrl → src 직접 바인딩
             referrerPolicy="no-referrer": localhost 레퍼러 차단 → 익명 요청 유지 */}
        <img
          src={url}
          alt="Dream Canvas"
          loading="lazy"
          referrerPolicy="no-referrer"
          crossOrigin="anonymous"
          style={{
            position:'absolute', inset:0,
            width:'100%', height:'100%',
            objectFit:'cover', zIndex:2, borderRadius:'14px'
          }}
        />
        <div style={{
          position:'absolute', inset:0, zIndex:3, pointerEvents:'none',
          background:'radial-gradient(ellipse at 50% 50%,transparent 55%,rgba(0,0,0,.38) 100%)'
        }}/>
      </div>
      <p style={{ textAlign:'center', marginTop:'10px',
        color:'rgba(245,158,11,.45)', fontSize:'.62rem',
        letterSpacing:'.14em', fontStyle:'italic' }}>
        {L.freeCanvasCaption}
      </p>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   2. SajuPremiumSection — 천기문 스타일 카테고리 리포트
      border-l-4 border-amber-500 통일 강조선
───────────────────────────────────────────────────────────────────── */
function SajuPremiumSection({ section, iconColor, icon, index }) {
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => setVisible(true), 120 * (index || 0));
    return () => clearTimeout(t);
  }, [index]);
  if (!section?.content) return null;

  return (
    <div style={{
      borderRadius:'14px', marginBottom:'18px', overflow:'hidden',
      border:'1px solid rgba(245,158,11,.2)',
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0)' : 'translateY(16px)',
      transition:'opacity .55s ease, transform .55s ease'
    }}>
      {/* 헤더 — amber-500 border-l-4 */}
      <div style={{
        display:'flex', alignItems:'center', gap:'10px',
        padding:'13px 18px',
        borderLeft:'4px solid #f59e0b',
        background:'linear-gradient(90deg,rgba(245,158,11,.12),rgba(245,158,11,.05),transparent)',
        borderBottom:'1px solid rgba(245,158,11,.15)'
      }}>
        <span style={{ fontSize:'1.1rem', flexShrink:0,
          filter:`drop-shadow(0 0 6px ${iconColor || '#f59e0b'})` }}>{icon}</span>
        <h4 style={{
          color:'#fbbf24', fontSize:'.78rem', fontWeight:700,
          letterSpacing:'.08em', fontFamily:'Noto Serif KR,serif', lineHeight:1.4
        }}>
          {section.title}
        </h4>
      </div>
      {/* 본문 */}
      <div style={{
        padding:'18px 18px 18px 22px',
        background:'linear-gradient(180deg,rgba(245,158,11,.04),transparent)'
      }}>
        <p style={{
          color:'rgba(255,255,255,.88)', fontSize:'.84rem',
          lineHeight:2.05, whiteSpace:'pre-line'
        }}>
          {section.content}
        </p>
      </div>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   3. ManseokTable — 오행 색상 2×4 만세력 테이블
───────────────────────────────────────────────────────────────────── */
function ManseokTable({ pillars, name, lang }) {
  const L = LANG[lang];
  const cols = [
    { key:'hour',  ko:'시주(時柱)', en:'Hour' },
    { key:'day',   ko:'일주(日柱)', en:'Day' },
    { key:'month', ko:'월주(月柱)', en:'Month' },
    { key:'year',  ko:'년주(年柱)', en:'Year' }
  ];
  return (
    <div className="premium-reveal" style={{
      background:'rgba(245,158,11,.04)',
      border:'1px solid rgba(245,158,11,.28)', borderRadius:'16px',
      padding:'16px 14px', marginBottom:'18px'
    }}>
      <p style={{ textAlign:'center', color:'rgba(251,191,36,.7)',
        fontSize:'.68rem', letterSpacing:'.12em', textTransform:'uppercase',
        marginBottom:'14px' }}>
        ⊹ {name}{lang==='ko' ? ' 님의 ' : ' — '}{L.premManseok} ⊹
      </p>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(4,1fr)', gap:'8px' }}>
        {cols.map(col => {
          const p  = pillars[col.key];
          const sC = EL_COLORS[p.stemEl]   || EL_COLORS['土'];
          const bC = EL_COLORS[p.branchEl] || EL_COLORS['水'];
          return (
            <div key={col.key}>
              <p style={{ textAlign:'center', fontSize:'.58rem',
                color:'rgba(255,255,255,.32)', marginBottom:'6px', lineHeight:1.3 }}>
                {lang==='ko' ? col.ko : col.en}
              </p>
              <div style={{ background:sC.bg, border:`1px solid ${sC.b}`,
                borderRadius:'8px 8px 0 0', padding:'10px 2px', textAlign:'center' }}>
                <div style={{ color:sC.text, fontSize:'1.55rem', fontWeight:900, fontFamily:'serif' }}>
                  {p.stem}
                </div>
                <div style={{ color:sC.text, fontSize:'.56rem', opacity:.75, marginTop:'2px' }}>
                  {p.stemEl}
                </div>
              </div>
              <div style={{ background:bC.bg, border:`1px solid ${bC.b}`,
                borderTop:'none', borderRadius:'0 0 8px 8px',
                padding:'10px 2px', textAlign:'center' }}>
                <div style={{ color:bC.text, fontSize:'1.55rem', fontWeight:900, fontFamily:'serif' }}>
                  {p.branch}
                </div>
                <div style={{ color:bC.text, fontSize:'.56rem', opacity:.75, marginTop:'2px' }}>
                  {p.branchEl}
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   4. FiveElementsDistribution — 오행 분포 (도넛 링 + 가로 바)
───────────────────────────────────────────────────────────────────── */
function FiveElementsDistribution({ pillars, lang }) {
  const isKo = lang === 'ko';
  const [animated, setAnimated] = useState(false);

  useEffect(() => {
    const t = setTimeout(() => setAnimated(true), 350);
    return () => clearTimeout(t);
  }, []);

  const counts = { '木':0,'火':0,'土':0,'金':0,'水':0 };
  ['year','month','day','hour'].forEach(k => {
    const p = pillars[k];
    if (counts[p.stemEl]   !== undefined) counts[p.stemEl]++;
    if (counts[p.branchEl] !== undefined) counts[p.branchEl]++;
  });
  const total = Object.values(counts).reduce((a,b) => a+b, 0) || 8;

  const EL = {
    '木': { ko:'목 (木) · 나무', en:'Wood  木', color:'#4ade80', emoji:'🌿' },
    '火': { ko:'화 (火) · 불',   en:'Fire  火', color:'#f87171', emoji:'🔥' },
    '土': { ko:'토 (土) · 흙',   en:'Earth 土', color:'#fbbf24', emoji:'🪨' },
    '金': { ko:'금 (金) · 쇠',   en:'Metal 金', color:'#cbd5e1', emoji:'⚙️' },
    '水': { ko:'수 (水) · 물',   en:'Water 水', color:'#60a5fa', emoji:'💧' }
  };

  /* 도넛 SVG 계산 */
  const elKeys = ['木','火','土','金','水'];
  const R = 42, CX = 56, CY = 56, stroke = 11;
  const circumference = 2 * Math.PI * R;
  let cumulative = 0;
  const arcs = elKeys.map(el => {
    const pct = counts[el] / total;
    const arc = { el, pct, offset: cumulative * circumference, dash: pct * circumference };
    cumulative += pct;
    return arc;
  });
  const dominant = elKeys.reduce((a, b) => counts[a] >= counts[b] ? a : b);

  return (
    <div style={{
      background:'rgba(245,158,11,.04)',
      border:'1px solid rgba(245,158,11,.22)',
      borderRadius:'16px', padding:'18px 16px', marginBottom:'18px'
    }}>
      <p style={{ textAlign:'center', color:'rgba(251,191,36,.65)',
        fontSize:'.68rem', letterSpacing:'.12em', textTransform:'uppercase',
        marginBottom:'16px' }}>
        {isKo ? '✦ 오행 기운 분포도' : '✦ Five Elements Distribution'}
      </p>

      {/* 도넛 차트 + 지배 오행 배지 */}
      <div style={{ display:'flex', alignItems:'center', gap:'18px', marginBottom:'18px' }}>
        <div style={{ flexShrink:0, position:'relative', width:'112px', height:'112px' }}>
          <svg width="112" height="112" viewBox="0 0 112 112">
            {/* 배경 트랙 */}
            <circle cx={CX} cy={CY} r={R}
              fill="none" stroke="rgba(255,255,255,.06)" strokeWidth={stroke}/>
            {/* 오행 아크 */}
            {arcs.map(({ el, pct, offset, dash }) => pct > 0 && (
              <circle key={el} cx={CX} cy={CY} r={R} fill="none"
                stroke={EL[el].color}
                strokeWidth={stroke}
                strokeDasharray={`${animated ? dash : 0} ${circumference}`}
                strokeDashoffset={-offset}
                strokeLinecap="butt"
                style={{ transition:'stroke-dasharray 1.4s cubic-bezier(.22,.61,.36,1)',
                  transform:'rotate(-90deg)', transformOrigin:`${CX}px ${CY}px` }}/>
            ))}
            {/* 중앙 텍스트 */}
            <text x={CX} y={CY - 7} textAnchor="middle"
              fill={EL[dominant].color} fontSize="18" fontWeight="900" fontFamily="serif">
              {dominant}
            </text>
            <text x={CX} y={CY + 9} textAnchor="middle"
              fill="rgba(255,255,255,.38)" fontSize="8" fontFamily="sans-serif">
              {isKo ? '주기운' : 'Dominant'}
            </text>
          </svg>
        </div>

        {/* 지배 오행 설명 배지 */}
        <div style={{ flex:1 }}>
          <div style={{
            background:`linear-gradient(135deg,${EL[dominant].color}18,${EL[dominant].color}08)`,
            border:`1px solid ${EL[dominant].color}44`,
            borderRadius:'10px', padding:'10px 12px', marginBottom:'8px'
          }}>
            <div style={{ color:EL[dominant].color, fontSize:'.8rem', fontWeight:700, marginBottom:'3px' }}>
              {EL[dominant].emoji} {isKo ? EL[dominant].ko : EL[dominant].en}
            </div>
            <div style={{ color:'rgba(255,255,255,.48)', fontSize:'.68rem', lineHeight:1.5 }}>
              {isKo ? '가장 강한 기운 · 이번 꿈의 핵심 에너지' : 'Dominant energy · Core dream force'}
            </div>
          </div>
          <div style={{ color:'rgba(255,255,255,.28)', fontSize:'.65rem', textAlign:'center' }}>
            {isKo ? `총 8글자 분석` : `8 pillars analyzed`}
          </div>
        </div>
      </div>

      {/* 가로 게이지 바 */}
      {elKeys.map(el => {
        const cnt = counts[el];
        const pct = Math.round((cnt / total) * 100);
        return (
          <div key={el} style={{ marginBottom:'11px' }}>
            <div style={{ display:'flex', justifyContent:'space-between',
              alignItems:'center', marginBottom:'4px' }}>
              <span style={{ color:EL[el].color, fontSize:'.78rem', fontWeight:700 }}>
                {EL[el].emoji} {isKo ? EL[el].ko : EL[el].en}
              </span>
              <span style={{ color:EL[el].color, fontSize:'.74rem', fontWeight:700,
                fontVariantNumeric:'tabular-nums' }}>
                {cnt}{isKo ? '개' : ''} · {pct}%
              </span>
            </div>
            <div style={{ height:'8px', background:'rgba(255,255,255,.07)',
              borderRadius:'4px', overflow:'hidden' }}>
              <div style={{
                height:'100%', borderRadius:'4px',
                width: animated ? `${pct}%` : '0%',
                background:`linear-gradient(90deg,${EL[el].color}55,${EL[el].color})`,
                boxShadow:`0 0 8px ${EL[el].color}44`,
                transition:'width 1.3s cubic-bezier(.22,.61,.36,1)'
              }}/>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   5. FortuneFlowChart — 향후 3개월 운세 에너지 흐름도 (SVG)
───────────────────────────────────────────────────────────────────── */
function FortuneFlowChart({ dreamText, mood, gauges, lang }) {
  const isKo = lang === 'ko';
  const [appear, setAppear] = useState(false);

  useEffect(() => {
    const t = setTimeout(() => setAppear(true), 200);
    return () => clearTimeout(t);
  }, []);

  const gaugeAvg = Array.isArray(gauges) && gauges.length
    ? Math.round(gauges.reduce((a, g) => a + (g.percent || 60), 0) / gauges.length)
    : (mood === 'good' ? 68 : 44);

  const h = (dreamText || '').split('').reduce((a, c) => a + c.charCodeAt(0), 0);
  const vals = [
    Math.max(28, Math.min(93, gaugeAvg)),
    Math.max(28, Math.min(93, gaugeAvg + ((h * 3) % 24) - 10)),
    Math.max(28, Math.min(93, gaugeAvg + ((h * 7) % 30) - 14))
  ];

  const MONTHS = isKo
    ? ['이번 달', '다음 달', '3개월 후']
    : ['This Month', 'Next Month', '3 Months'];

  const W = 300, H = 90, PAD = 28;
  const xs = [PAD, W / 2, W - PAD];
  const yRange = H - PAD * 0.8;
  const ys = vals.map(v => H - PAD * 0.4 - (v / 100) * yRange);

  const seg = (x1, y1, x2, y2) => {
    const mx = (x1 + x2) / 2;
    return `C ${mx},${y1} ${mx},${y2} ${x2},${y2}`;
  };
  const lineD = `M ${xs[0]},${ys[0]} ${seg(xs[0],ys[0],xs[1],ys[1])} ${seg(xs[1],ys[1],xs[2],ys[2])}`;
  const areaD = `${lineD} L ${xs[2]},${H + 10} L ${xs[0]},${H + 10} Z`;

  const color = mood === 'good' ? '#f59e0b' : '#f87171';
  const trend = vals[2] > vals[0] ? 'up' : vals[2] < vals[0] ? 'down' : 'flat';
  const trendMeta = {
    up:   { icon:'▲', ko:'3개월 상승 추세', en:'Rising Trend',   col:'#4ade80' },
    down: { icon:'▼', ko:'3개월 하강 (주의)', en:'Declining',    col:'#f87171' },
    flat: { icon:'—', ko:'안정 유지 추세', en:'Stable',          col:'#fbbf24' }
  }[trend];

  return (
    <div style={{
      background:'rgba(245,158,11,.04)',
      border:'1px solid rgba(245,158,11,.2)',
      borderRadius:'16px', padding:'18px 16px 12px', marginBottom:'18px',
      opacity: appear ? 1 : 0, transition:'opacity .6s ease'
    }}>
      {/* 헤더 */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:'12px' }}>
        <p style={{ color:'rgba(251,191,36,.65)', fontSize:'.68rem',
          letterSpacing:'.1em', textTransform:'uppercase' }}>
          {isKo ? '✦ 향후 3개월 운세 흐름' : '✦ Fortune Flow (3 Months)'}
        </p>
        <span style={{
          color: trendMeta.col, fontSize:'.68rem', fontWeight:700,
          background:`${trendMeta.col}14`, border:`1px solid ${trendMeta.col}33`,
          borderRadius:'20px', padding:'2px 10px', letterSpacing:'.04em'
        }}>
          {trendMeta.icon} {isKo ? trendMeta.ko : trendMeta.en}
        </span>
      </div>

      <svg width="100%" viewBox={`0 0 ${W} ${H + 32}`} style={{ overflow:'visible', display:'block' }}>
        <defs>
          <linearGradient id="flowAreaGrad2" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"   stopColor={color} stopOpacity="0.35"/>
            <stop offset="100%" stopColor={color} stopOpacity="0.02"/>
          </linearGradient>
          <filter id="glowF">
            <feGaussianBlur stdDeviation="2" result="blur"/>
            <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
          </filter>
        </defs>

        {/* 그리드 점선 */}
        {[25, 50, 75].map(pct => {
          const gy = H - PAD * 0.4 - (pct / 100) * yRange;
          return (
            <g key={pct}>
              <line x1={PAD} y1={gy} x2={W - PAD} y2={gy}
                stroke="rgba(255,255,255,.07)" strokeWidth="1" strokeDasharray="4,5"/>
              <text x={PAD - 5} y={gy + 4} textAnchor="end"
                fill="rgba(255,255,255,.2)" fontSize="8" fontFamily="monospace">{pct}</text>
            </g>
          );
        })}

        {/* 영역 채우기 */}
        <path d={areaD} fill="url(#flowAreaGrad2)"/>

        {/* 글로우 라인 */}
        <path d={lineD} fill="none" stroke={color} strokeWidth="4"
          strokeLinecap="round" strokeLinejoin="round" opacity="0.25" filter="url(#glowF)"/>
        {/* 메인 라인 */}
        <path d={lineD} fill="none" stroke={color} strokeWidth="2.5"
          strokeLinecap="round" strokeLinejoin="round"/>

        {/* 데이터 포인트 */}
        {xs.map((x, i) => (
          <g key={i}>
            <circle cx={x} cy={ys[i]} r="10" fill={color} opacity="0.15"/>
            <circle cx={x} cy={ys[i]} r="5.5" fill={color}
              stroke="rgba(5,5,16,.9)" strokeWidth="2.5"/>
            <text x={x} y={ys[i] - 13} textAnchor="middle"
              fill={color} fontSize="10" fontWeight="700" fontFamily="monospace">
              {vals[i]}%
            </text>
            <text x={x} y={H + 24} textAnchor="middle"
              fill="rgba(255,255,255,.4)" fontSize="9" fontFamily="sans-serif">
              {MONTHS[i]}
            </text>
          </g>
        ))}
      </svg>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   6. GaugeBar + GaugesSection — 운세 카테고리별 게이지 바
───────────────────────────────────────────────────────────────────── */
function GaugeBar({ label, labelEn, icon, percent, advice, adviceEn, lang, index }) {
  const [width, setWidth] = useState(0);
  useEffect(() => {
    const t = setTimeout(() => setWidth(percent), 320 + index * 170);
    return () => clearTimeout(t);
  }, [percent, index]);
  const color = gaugeColor(percent);
  return (
    <div style={{ marginBottom:'18px' }}>
      <div style={{ display:'flex', justifyContent:'space-between',
        alignItems:'center', marginBottom:'6px' }}>
        <span style={{ color:'rgba(255,255,255,.88)', fontSize:'.84rem', fontWeight:600 }}>
          {icon} {lang==='ko' ? label : labelEn}
        </span>
        <span style={{ color, fontWeight:700, fontSize:'.84rem',
          fontVariantNumeric:'tabular-nums' }}>
          {percent}%
        </span>
      </div>
      <div className="gauge-track">
        <div className="gauge-fill"
          style={{ width:`${width}%`,
            background:`linear-gradient(90deg,${color}66,${color})`,
            boxShadow:`0 0 10px ${color}55` }}/>
      </div>
      <p style={{ color:'rgba(255,255,255,.4)', fontSize:'.7rem',
        marginTop:'5px', lineHeight:1.55 }}>
        {lang==='ko' ? advice : adviceEn}
      </p>
    </div>
  );
}

function GaugesSection({ gauges, lang }) {
  const L = LANG[lang];
  if (!Array.isArray(gauges) || gauges.length === 0) return null;

  /* 총 행운 지수 평균 */
  const avgScore = Math.round(gauges.reduce((a, g) => a + (g.percent || 0), 0) / gauges.length);
  const avgColor = gaugeColor(avgScore);

  return (
    <div style={{
      background:'rgba(245,158,11,.04)',
      border:'1px solid rgba(245,158,11,.2)',
      borderRadius:'16px', padding:'18px 16px', marginBottom:'20px'
    }}>
      {/* 섹션 헤더 + 총점 배지 */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:'18px' }}>
        <p style={{ color:'rgba(251,191,36,.65)', fontSize:'.68rem',
          letterSpacing:'.12em', textTransform:'uppercase' }}>
          {L.sajuGaugeSection}
        </p>
        <div style={{
          background:`${avgColor}14`, border:`1px solid ${avgColor}44`,
          borderRadius:'20px', padding:'3px 12px',
          color: avgColor, fontSize:'.72rem', fontWeight:700
        }}>
          {lang==='ko' ? `종합 ${avgScore}점` : `Overall ${avgScore}`}
        </div>
      </div>
      {gauges.map((g, i) => <GaugeBar key={i} index={i} lang={lang} {...g}/>)}
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   7. GrandTalismanCard — 금빛 오라 황금 트리플 프레임 부적 카드
      캡처하기 좋은 액자형 + 상단 금인장 씰 디자인
───────────────────────────────────────────────────────────────────── */
function GrandTalismanCard({ url, mood, cardName, lang }) {
  const isKo = lang === 'ko';
  const [status,    setStatus]    = useState('loading');
  const [unlocking, setUnlocking] = useState(false);
  const imgRef   = useRef(null);
  const retried  = useRef(false);
  const retryRef = useRef(null);

  useEffect(() => {
    if (!url) return;
    const img = imgRef.current;
    if (img && img.complete && img.naturalWidth > 0) setStatus('loaded');
  }, [url]);
  useEffect(() => () => clearTimeout(retryRef.current), []);
  useEffect(() => {
    if (!url || status !== 'loading') return;
    const t = setTimeout(() => setStatus('timeout'), 180000);
    return () => clearTimeout(t);
  }, [url, status]);
  useEffect(() => {
    const t = setTimeout(() => setUnlocking(true), 600);
    return () => clearTimeout(t);
  }, []);

  const handleError = () => {
    if (!retried.current) {
      retried.current = true;
      retryRef.current = setTimeout(() => {
        setStatus('loading');
        if (imgRef.current && url) imgRef.current.src = url + '&_r=1';
      }, 5000);
    } else { setStatus('error'); }
  };
  const showSpin = !url || status === 'loading';
  const showFall = status === 'error' || status === 'timeout';

  const outerGlow = unlocking
    ? '0 0 0 1px rgba(212,175,55,.6), 0 0 40px rgba(212,175,55,.5), 0 0 100px rgba(212,175,55,.22), 0 0 180px rgba(212,175,55,.1)'
    : '0 0 0 1px rgba(212,175,55,.22)';

  return (
    <div style={{ position:'relative' }}>

      {/* ── 상단 금인장 씰 배지 ── */}
      <div style={{ textAlign:'center', marginBottom:'16px', position:'relative', zIndex:5 }}>
        <div style={{
          display:'inline-flex', flexDirection:'column', alignItems:'center',
          gap:'5px'
        }}>
          {/* 씰 원 */}
          <div style={{
            width:'58px', height:'58px', borderRadius:'50%',
            background:'linear-gradient(135deg,#2d1a00,#1a0e00)',
            border:'2px solid #d4af37',
            boxShadow: unlocking
              ? '0 0 22px rgba(212,175,55,.75), 0 0 50px rgba(212,175,55,.35)'
              : '0 0 10px rgba(212,175,55,.3)',
            display:'flex', alignItems:'center', justifyContent:'center',
            transition:'box-shadow 1.2s ease',
            position:'relative'
          }}>
            {/* 씰 내부 원 */}
            <div style={{
              position:'absolute', inset:'5px', borderRadius:'50%',
              border:'1px solid rgba(212,175,55,.4)'
            }}/>
            <span style={{ fontSize:'1.5rem', filter:'drop-shadow(0 0 8px rgba(212,175,55,.8))' }}>⛩️</span>
          </div>
          <span style={{
            color:'rgba(212,175,55,.75)', fontSize:'.62rem',
            letterSpacing:'.28em', textTransform:'uppercase',
            fontFamily:'Cinzel,serif',
            textShadow: unlocking ? '0 0 14px rgba(212,175,55,.6)' : 'none',
            transition:'text-shadow 1.2s ease'
          }}>
            {isKo ? '귀하만을 위한 수호 부적' : 'Your Personal Guardian Talisman'}
          </span>
        </div>
      </div>

      {/* ── 외부 황금 프레임 (가장 바깥) ── */}
      <div style={{
        background:'linear-gradient(155deg,#160800,#220d00,#0e0400)',
        border:'2px solid #d4af37', borderRadius:'20px', padding:'10px',
        boxShadow: outerGlow, transition:'box-shadow 1.4s ease'
      }}>

        {/* ── 중간 은은한 프레임 ── */}
        <div style={{
          border:'1px solid rgba(212,175,55,.3)',
          borderRadius:'12px', padding:'6px',
          background:'linear-gradient(180deg,rgba(212,175,55,.05),transparent)'
        }}>

          {/* ── 이미지 컨테이너 ── */}
          <div style={{
            border:'1px solid rgba(212,175,55,.2)',
            borderRadius:'8px', overflow:'hidden',
            position:'relative', aspectRatio:'2/3',
            background:'linear-gradient(180deg,#1a0500,#0d0300)'
          }}>

            {/* 코너 장식 */}
            {[
              { top:'8px',    left:'8px',    borderTop:'2px solid rgba(212,175,55,.7)', borderLeft:'2px solid rgba(212,175,55,.7)',   borderRadius:'3px 0 0 0' },
              { top:'8px',    right:'8px',   borderTop:'2px solid rgba(212,175,55,.7)', borderRight:'2px solid rgba(212,175,55,.7)',  borderRadius:'0 3px 0 0' },
              { bottom:'8px', left:'8px',    borderBottom:'2px solid rgba(212,175,55,.7)', borderLeft:'2px solid rgba(212,175,55,.7)',   borderRadius:'0 0 0 3px' },
              { bottom:'8px', right:'8px',   borderBottom:'2px solid rgba(212,175,55,.7)', borderRight:'2px solid rgba(212,175,55,.7)',  borderRadius:'0 0 3px 0' }
            ].map((s, i) => (
              <div key={i} style={{ position:'absolute', width:'24px', height:'24px', zIndex:10, ...s }}/>
            ))}

            {/* 로딩 스켈레톤 */}
            {showSpin && (
              <>
                <div className="panel-skeleton-amber" style={{ borderRadius:'7px' }}/>
                <div style={{ position:'absolute', inset:0, display:'flex',
                  flexDirection:'column', alignItems:'center', justifyContent:'center',
                  zIndex:5, gap:'18px' }}>
                  <div className="spin-anim" style={{
                    width:'60px', height:'60px', borderRadius:'50%',
                    border:'3px solid rgba(212,175,55,.12)', borderTopColor:'#d4af37',
                    boxShadow:'0 0 30px rgba(212,175,55,.6)'
                  }}/>
                  <span style={{
                    color:'rgba(212,175,55,.62)', fontSize:'.72rem',
                    letterSpacing:'.12em', textAlign:'center', lineHeight:1.65,
                    whiteSpace:'pre-line'
                  }}>
                    {isKo ? '귀하만을 위한 부적을\n완성하는 중...' : 'Crafting your\npersonal talisman...'}
                  </span>
                </div>
              </>
            )}

            {/* 에러 폴백 */}
            {showFall && (
              <div style={{ position:'absolute', inset:0, zIndex:2,
                background:'radial-gradient(ellipse at 50% 30%,#2d0e00,#080200)',
                display:'flex', flexDirection:'column',
                alignItems:'center', justifyContent:'center', gap:'14px' }}>
                <span style={{ fontSize:'5.5rem',
                  filter:'drop-shadow(0 0 40px rgba(212,175,55,.85))' }}>⛩️</span>
                <span style={{ color:'rgba(212,175,55,.5)', fontSize:'.68rem',
                  letterSpacing:'.1em' }}>
                  {isKo ? '신탁이 준비 중입니다' : 'Oracle preparing...'}
                </span>
              </div>
            )}

            {/* 부적 이미지 */}
            {url && (
              <img ref={imgRef} src={url} alt={cardName || '수호 부적'}
                referrerPolicy="no-referrer"
                style={{ position:'absolute', inset:0, width:'100%', height:'100%',
                  objectFit:'cover', zIndex:3,
                  opacity: status === 'loaded' ? 1 : 0, transition:'opacity 1.5s ease',
                  animation: unlocking && status === 'loaded'
                    ? 'revealCard 2s cubic-bezier(.4,0,.2,1) forwards' : 'none' }}
                onLoad={() => setStatus('loaded')} onError={handleError} />
            )}

            {/* 하단 그라데이션 */}
            {status === 'loaded' && (
              <div style={{ position:'absolute', bottom:0, left:0, right:0, zIndex:4,
                height:'30%', pointerEvents:'none',
                background:'linear-gradient(to top,rgba(0,0,0,.72) 0%,transparent 100%)' }}/>
            )}
          </div>
        </div>

        {/* ── 하단 금색 명패 ── */}
        <div style={{
          marginTop:'8px',
          padding:'8px 12px',
          borderTop:'1px solid rgba(212,175,55,.2)',
          textAlign:'center',
          opacity: unlocking ? 1 : 0,
          transition:'opacity 1s ease .8s'
        }}>
          {cardName && (
            <span style={{
              color:'#d4af37', fontFamily:'Noto Serif KR,serif',
              fontWeight:700, fontSize:'1.0rem', letterSpacing:'.18em',
              textShadow:'0 0 20px rgba(212,175,55,.9), 0 0 45px rgba(212,175,55,.4)'
            }}>
              {cardName}
            </span>
          )}
        </div>
      </div>

      {/* ── 하단 워터마크 ── */}
      <div style={{ textAlign:'center', marginTop:'12px',
        opacity: unlocking ? 0.5 : 0, transition:'opacity 1.2s ease 1.2s' }}>
        <span style={{ color:'rgba(212,175,55,.4)', fontSize:'.58rem',
          letterSpacing:'.22em', textTransform:'uppercase', fontFamily:'Cinzel,serif' }}>
          ✦ Dream Oracle ✦
        </span>
      </div>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   8. SajuResult — 결과 화면 (전체 레이아웃)
───────────────────────────────────────────────────────────────────── */
function SajuResult({ lang, mood, basicData, dreamText, onRestart }) {
  const L   = LANG[lang];
  const acc = '#f59e0b', accL = '#fde68a';
  const bg  = 'radial-gradient(ellipse at 50% 0%,#0d0500 0%,#050510 65%)';

  const [premPhase,   setPremPhase]   = useState(null);
  const [adProg,      setAdProg]      = useState(0);
  const [form,        setForm]        = useState({
    name:'', birthYear:'', birthMonth:'', birthDay:'', birthHour:'-1'
  });
  const [formErr,     setFormErr]     = useState('');
  const [premiumData, setPremiumData] = useState(null);
  const [pillars,     setPillars]     = useState(null);
  const adRef = useRef(null);

  const freeImgUrl = useMemo(
    () => buildFreeImageUrl(dreamText, mood, dreamText.slice(0,30) + 'saju', 'saju'),
    [] // eslint-disable-line
  );

  const [premImgUrl, setPremImgUrl] = useState(null);
  const premImgBuilt = useRef(false);

  const startAd = () => {
    setPremPhase('watching');
    let p = 0;
    adRef.current = setInterval(() => {
      p += 100 / 300;
      setAdProg(Math.min(p, 100));
      if (p >= 100) { clearInterval(adRef.current); setTimeout(() => setPremPhase('form'), 500); }
    }, 100);
  };
  useEffect(() => () => clearInterval(adRef.current), []);
  const secsLeft = Math.ceil(30 * (1 - adProg / 100));

  const validate = () => {
    if (!form.name.trim())                                     { setFormErr(L.premSubmitValidName);  return false; }
    if (!form.birthYear || !form.birthMonth || !form.birthDay) { setFormErr(L.premSubmitValidBirth); return false; }
    setFormErr(''); return true;
  };

  const submitPremium = async () => {
    if (!validate()) return;
    setPremPhase('generating');

    /* 꿈 텍스트 기반 수호 부적 URL 즉시 생성 (AI 대기 없음) */
    if (!premImgBuilt.current) {
      premImgBuilt.current = true;
      const rawDream = dreamText.trim().replace(/^[pP]\//, '');
      setPremImgUrl(
        `https://image.pollinations.ai/p/flux/${encodeURIComponent(rawDream)},%20an%20ancient%20oriental%20mystic%20talisman%20design,%20sacred%20divine%20glow,%20spiritual%20energy%20patterns,%20no%20text,%208k`
      );
    }

    try {
      setPillars(calcFourPillars(
        parseInt(form.birthYear), parseInt(form.birthMonth),
        parseInt(form.birthDay),
        form.birthHour === '-1' ? 0 : parseInt(form.birthHour)
      ));
    } catch (e) {}
    try {
      const data = await generatePremiumSajuReading(dreamText, mood, lang, form);
      setPremiumData(data);
    } catch (err) {
      console.warn('[SajuModule] fallback:', err.message);
      setPremiumData(generateLocalPremiumSajuFallback(dreamText, mood, lang, form));
    }
    setPremPhase('done');
  };

  /* 섹션별 아이콘 + 색상 */
  const SECTION_CFG = [
    { key:'destiny', icon:'☯️',  iconColor:'#fbbf24' },
    { key:'wealth',  icon:'💰',  iconColor:'#4ade80' },
    { key:'advice',  icon:'🛡️', iconColor:'#f87171' }
  ];

  return (
    <div className="relative min-h-screen px-4 py-8" style={{ background:bg }}>
      <Stars/>
      <div className="relative z-10 max-w-md mx-auto">

        {/* ① 결과 헤더 */}
        <div className="text-center pt-4 mb-7">
          <div className="inline-block px-3 py-1 rounded-full text-xs font-bold tracking-widest uppercase mb-3"
            style={{ background:`${acc}18`, color:acc, border:`1px solid ${acc}33` }}>
            {L.readingHeader.saju}
          </div>
          <h2 className="font-black text-2xl md:text-3xl mb-2"
            style={{ color:accL, fontFamily:'Noto Serif KR,serif' }}>
            {basicData.title}
          </h2>
          <p className="text-sm" style={{ color:acc }}>{basicData.subtitle}</p>
        </div>

        {/* ② 무료 해몽 텍스트 */}
        <Divider label={L.oracleSection.saju} color={acc}/>
        <div className="glass rounded-2xl p-6 mb-8"
          style={{ borderColor:`${acc}44`,
            background:'linear-gradient(135deg,rgba(0,0,0,.42),rgba(245,158,11,.05))' }}>
          <div className="flex items-center gap-2 mb-3">
            <span>⛩️</span>
            <span className="text-xs font-bold tracking-widest uppercase" style={{ color:acc }}>
              {L.oracleLabel.saju}
            </span>
          </div>
          <p className="reading-text text-gray-200 text-sm">{sanitize(basicData.readingText)}</p>
        </div>

        {/* ③ Oriental Mystic Fantasy 캔버스 */}
        <SajuFreeDreamArt url={freeImgUrl} lang={lang}/>

        {/* ④ 프리미엄 게이트 */}
        {premPhase === null && (
          <div style={{ background:'linear-gradient(135deg,rgba(146,64,14,.22),rgba(0,0,0,.55))',
            border:`1px solid ${acc}55`, borderRadius:'20px',
            padding:'26px 20px', marginBottom:'24px' }}>
            <div className="text-center mb-5">
              <div style={{ fontSize:'1.6rem', marginBottom:'10px' }}>🔒</div>
              <h3 className="font-black text-base mb-1" style={{ color:accL }}>
                {L.premGateTitle}
              </h3>
              <p className="text-sm leading-relaxed mt-2"
                style={{ color:'rgba(255,255,255,.62)', lineHeight:1.75 }}>
                {L.premGateNewDesc.saju}
              </p>
            </div>
            <ul className="mb-6 space-y-2">
              {L.premFeatures.saju.map((f,i) => (
                <li key={i} className="text-sm" style={{ color:'rgba(255,255,255,.72)' }}>{f}</li>
              ))}
            </ul>
            <div className="flex flex-col gap-3">
              <button onClick={startAd}
                className="w-full py-4 rounded-xl font-black text-sm cursor-pointer"
                style={{ background:`linear-gradient(135deg,${acc},#dc2626)`,
                  boxShadow:`0 0 30px ${acc}55` }}>
                {L.premAdBtn}
              </button>
              <button onClick={() => setPremPhase('form')}
                className="w-full py-3 rounded-xl font-black text-sm cursor-pointer"
                style={{ background:'linear-gradient(135deg,#78350f,#b45309)',
                  boxShadow:'0 0 22px rgba(180,83,9,.4)', color:'white' }}>
                {L.premPayBtn}
              </button>
            </div>
          </div>
        )}

        {/* ⑤ 광고 진행바 */}
        {premPhase === 'watching' && (
          <div className="glass rounded-2xl p-6 mb-6" style={{ borderColor:`${acc}44` }}>
            <div className="flex items-center justify-between mb-3">
              <span className="text-gray-400 text-sm">{L.premAdPlaying}</span>
              <span className="font-black tabular-nums" style={{ color:acc, fontSize:'1.2rem' }}>
                {secsLeft}s
              </span>
            </div>
            <div className="w-full bg-gray-900 rounded-full mb-4" style={{ height:'5px' }}>
              <div className="prog-bar rounded-full"
                style={{ width:`${adProg}%`, background:`linear-gradient(90deg,${acc},#dc2626)` }}/>
            </div>
            <div className="rounded-xl p-5 text-center"
              style={{ background:'rgba(255,255,255,.03)', border:'1px dashed rgba(255,255,255,.08)' }}>
              <div className="text-gray-600 text-xs mb-1">[ AD PLACEHOLDER ]</div>
              <div className="text-gray-700 text-xs">Google AdSense / AdMob 광고 영역</div>
            </div>
            {adProg >= 100 && (
              <p className="text-center text-sm font-bold mt-3" style={{ color:'#4ade80' }}>
                {L.premAdDone}
              </p>
            )}
          </div>
        )}

        {/* ⑥ 이름/생년월일시 입력 폼 */}
        {premPhase === 'form' && (
          <div className="glass rounded-2xl p-6 mb-6 premium-reveal"
            style={{ borderColor:`${acc}55`,
              background:'linear-gradient(135deg,rgba(146,64,14,.13),rgba(0,0,0,.42))' }}>
            <h3 className="font-black text-base text-center mb-5" style={{ color:accL }}>
              {L.premFormTitle.saju}
            </h3>
            <div className="mb-4">
              <label className="form-label">{L.premNameLabel}</label>
              <input className="form-input" type="text" placeholder={L.premNamePh}
                value={form.name} onChange={e => setForm({...form,name:e.target.value})}
                maxLength={30}/>
            </div>
            <div className="mb-4">
              <label className="form-label">{L.premYearLabel}</label>
              <input className="form-input" type="number" placeholder={L.premYearPh}
                value={form.birthYear} onChange={e => setForm({...form,birthYear:e.target.value})}
                min="1900" max="2025"/>
            </div>
            <div className="flex gap-3 mb-4">
              <div className="flex-1">
                <label className="form-label">{L.premMonthLabel}</label>
                <select className="form-select" value={form.birthMonth}
                  onChange={e => setForm({...form,birthMonth:e.target.value})}>
                  <option value="">--</option>
                  {Array.from({length:12},(_,i)=>(
                    <option key={i+1} value={String(i+1)}>{i+1}</option>
                  ))}
                </select>
              </div>
              <div className="flex-1">
                <label className="form-label">{L.premDayLabel}</label>
                <select className="form-select" value={form.birthDay}
                  onChange={e => setForm({...form,birthDay:e.target.value})}>
                  <option value="">--</option>
                  {Array.from({length:31},(_,i)=>(
                    <option key={i+1} value={String(i+1)}>{i+1}</option>
                  ))}
                </select>
              </div>
            </div>
            <div className="mb-4">
              <label className="form-label">{L.premHourLabel}</label>
              <div style={{ position:'relative' }}>
                <select className="form-select" value={form.birthHour}
                  onChange={e => setForm({...form,birthHour:e.target.value})}>
                  {SAJU_HOURS.map(h => (
                    <option key={h.val} value={h.val}>{lang==='ko' ? h.ko : h.en}</option>
                  ))}
                </select>
                <span style={{ position:'absolute', right:'12px', top:'50%',
                  transform:'translateY(-50%)', pointerEvents:'none',
                  color:'rgba(255,255,255,.4)', fontSize:'.8rem' }}>▾</span>
              </div>
            </div>
            {formErr && (
              <p className="text-sm text-center mb-3" style={{ color:'#f87171' }}>{formErr}</p>
            )}
            <button onClick={submitPremium}
              className="w-full py-4 rounded-xl font-black text-base cursor-pointer"
              style={{ background:`linear-gradient(135deg,${acc},#dc2626)`,
                boxShadow:`0 0 32px ${acc}55` }}>
              {L.premSubmitBtn}
            </button>
          </div>
        )}

        {/* ⑦ AI 생성 중 */}
        {premPhase === 'generating' && (
          <div className="glass rounded-2xl p-8 mb-6 text-center premium-reveal"
            style={{ borderColor:`${acc}44` }}>
            <div className="inline-flex items-center justify-center w-20 h-20 mb-5 relative">
              <div className="spin-anim absolute inset-0 rounded-full"
                style={{ border:`2px solid transparent`, borderTopColor:acc,
                  boxShadow:`0 0 20px ${acc}88` }}/>
              <span style={{ fontSize:'2rem', filter:`drop-shadow(0 0 14px ${acc})` }}>⛩️</span>
            </div>
            <p className="text-white text-sm font-medium">{L.premGenerating.saju}</p>
          </div>
        )}

        {/* ⑧ 프리미엄 결과 — 천기문급 레이아웃 */}
        {premPhase === 'done' && premiumData && (
          <div className="premium-reveal">

            {/* PREMIUM 배지 */}
            <div className="text-center mb-8">
              <div className="inline-block px-3 py-1 rounded-full text-xs font-bold tracking-widest uppercase mb-3"
                style={{ background:'#f59e0b22', color:'#fbbf24', border:'1px solid #f59e0b44' }}>
                PREMIUM ORACLE · UNLOCKED ✦
              </div>
              <h3 className="font-black text-xl"
                style={{ color:accL, fontFamily:'Noto Serif KR,serif',
                  textShadow:`0 0 22px ${acc}88` }}>
                ✦ {premiumData.title} ✦
              </h3>
              <p className="text-sm mt-1" style={{ color:acc }}>{premiumData.subtitle}</p>
            </div>

            {/* [A] 오행 색상 만세력 테이블 */}
            {pillars && (
              <ManseokTable pillars={pillars} name={form.name.trim() || '?'} lang={lang}/>
            )}

            {/* [B] 오행 기운 분포 — 도넛 링 + 가로 게이지 */}
            {pillars && (
              <FiveElementsDistribution pillars={pillars} lang={lang}/>
            )}

            {/* [C] 향후 3개월 운세 에너지 흐름도 */}
            <FortuneFlowChart
              dreamText={dreamText}
              mood={mood}
              gauges={premiumData.gauges}
              lang={lang}
            />

            {/* [D] 운세 카테고리별 게이지 바 (재물/연애/건강/행운) */}
            <GaugesSection gauges={premiumData.gauges} lang={lang}/>

            {/* [E] 카테고리 리포트 — border-l-4 amber-500 천기문 스타일 */}
            <Divider label={L.premSection.saju} color="#fbbf24"/>
            <div style={{ marginBottom:'16px' }}>
              {SECTION_CFG.map((cfg, idx) => (
                <SajuPremiumSection
                  key={cfg.key}
                  section={premiumData.sections?.[cfg.key]}
                  icon={cfg.icon}
                  iconColor={cfg.iconColor}
                  index={idx}
                />
              ))}
            </div>

            {/* [F] 피날레 — 황금 트리플 액자 수호 부적 */}
            <Divider label={L.premCardSection.saju} color="#d4af37"/>
            <div className="mb-6">
              <GrandTalismanCard
                url={premImgUrl}
                mood={mood}
                cardName={premiumData.cardName
                  || (lang==='ko'
                    ? `${form.name.trim()}님 수호 부적`
                    : `${form.name.trim()}'s Guardian Talisman`)}
                lang={lang}
              />
            </div>
            <p className="text-center text-xs mb-8" style={{ color:`${acc}80` }}>
              {L.cardComplete.saju}
            </p>
          </div>
        )}

        {/* ⑨ 재시작 */}
        <div className="text-center pb-12 mt-2">
          <button onClick={onRestart}
            className="text-gray-600 hover:text-gray-400 text-sm transition-colors underline cursor-pointer">
            {L.restart.saju}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────────────
   9. SajuModule — 루트 (입력 → 로딩 → 결과)
───────────────────────────────────────────────────────────────────── */
window.SajuModule = function SajuModule({ lang, onBack }) {
  const [phase,         setPhase]         = useState('input');
  const [dreamText,     setDreamText]     = useState('');
  const [mood,          setMood]          = useState(null);
  const [basicData,     setBasicData]     = useState(null);
  const [loadPhase,     setLoadPhase]     = useState('analyzing');
  const [scriptPreview, setScriptPreview] = useState(null);

  const handleSubmit = async (txt, m) => {
    setDreamText(txt); setMood(m);
    setPhase('loading'); setLoadPhase('analyzing'); setScriptPreview(null);
    await new Promise(r => setTimeout(r, 900));
    setLoadPhase('scripting');
    let data;
    try {
      data = await generateBasicReading(txt, 'saju', m, lang);
      setScriptPreview(`"${data.title}"`);
    } catch (err) {
      console.warn('[SajuModule] basic fallback:', err.message);
      data = generateLocalBasicFallback(txt, 'saju', m, lang);
      setScriptPreview('(ready)');
    }
    setBasicData(data);
    await new Promise(r => setTimeout(r, 700));
    setLoadPhase('drawing');
    await new Promise(r => setTimeout(r, 500));
    setPhase('result');
  };

  const goInput = () => { setPhase('input'); setBasicData(null); setScriptPreview(null); };

  if (phase === 'input')
    return <DreamInput  lang={lang} theme="saju" onSubmit={handleSubmit} onBack={onBack}/>;
  if (phase === 'loading')
    return <Loading     lang={lang} theme="saju" phase={loadPhase} scriptPreview={scriptPreview}/>;
  if (phase === 'result')
    return <SajuResult  lang={lang} mood={mood} basicData={basicData} dreamText={dreamText} onRestart={goInput}/>;
  return null;
};
