// ── Spin Wheel ────────────────────────────────────────────────
const DEFAULT_SEGMENTS = [
  { id:'s1',  label:'Starbucks',       sub:'Drink up to $6',   emoji:'☕',  type:'win',     color:'#00704A', weight:1, enabled:true },
  { id:'s2',  label:"McDonald's",      sub:'Item up to $5',    emoji:'🍔',  type:'win',     color:'#DA291C', weight:1, enabled:true },
  { id:'s3',  label:'10-Min Back Rub', sub:'Partner owes you', emoji:'💆',  type:'win',     color:'#7A8B5E', weight:1, enabled:true },
  { id:'s4',  label:'Contribute $5',   sub:'Pick a goal',      emoji:'💸',  type:'bad',     color:'#B85850', weight:1, enabled:true },
  { id:'s5',  label:'Contribute $10',  sub:'Pick a goal',      emoji:'💸',  type:'bad',     color:'#8B5E3C', weight:1, enabled:true },
  { id:'s6',  label:'Contribute $5',   sub:'Pick a goal',      emoji:'💸',  type:'bad',     color:'#B85850', weight:1, enabled:true },
  { id:'s7',  label:'Re-Spin',         sub:'Spin again now!',  emoji:'🔄',  type:'neutral', color:'#8A7E72', weight:1, enabled:true },
  { id:'s8',  label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s9',  label:'Re-Spin',         sub:'Spin again now!',  emoji:'🔄',  type:'neutral', color:'#8A7E72', weight:1, enabled:true },
  { id:'s10', label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s11', label:'Re-Spin',         sub:'Spin again now!',  emoji:'🔄',  type:'neutral', color:'#8A7E72', weight:1, enabled:true },
  { id:'s12', label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s13', label:'Re-Spin',         sub:'Spin again now!',  emoji:'🔄',  type:'neutral', color:'#8A7E72', weight:1, enabled:true },
  { id:'s14', label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s15', label:'Play Tomorrow',   sub:'Free pass today',  emoji:'📅',  type:'neutral', color:'#5E7A8B', weight:1, enabled:true },
  { id:'s16', label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s17', label:'Play Tomorrow',   sub:'Free pass today',  emoji:'📅',  type:'neutral', color:'#5E7A8B', weight:1, enabled:true },
  { id:'s18', label:'5-Min Back Rub',  sub:'A little treat',   emoji:'🤲',  type:'win',     color:'#C8956D', weight:1, enabled:true },
  { id:'s19', label:'Play Tomorrow',   sub:'Free pass today',  emoji:'📅',  type:'neutral', color:'#5E7A8B', weight:1, enabled:true },
  { id:'s20', label:'Play Tomorrow',   sub:'Free pass today',  emoji:'📅',  type:'neutral', color:'#5E7A8B', weight:1, enabled:true },
];

const spinTodayKey = () => new Date().toLocaleDateString('en-CA');

function pickWeightedSegment(segments) {
  const pool = segments.filter(s => s.enabled !== false).flatMap(s => Array(s.weight || 1).fill(s));
  if (!pool.length) return segments[0];
  return pool[Math.floor(Math.random() * pool.length)];
}

function calcSpinStreak(spins, name) {
  let streak = 0;
  const today = new Date();
  for (let i = 0; i < 365; i++) {
    const d = new Date(today);
    d.setDate(d.getDate() - i);
    if (spins?.[d.toLocaleDateString('en-CA')]?.[name]) streak++;
    else if (i > 0) break;
  }
  return streak;
}

// ── Spin Wheel SVG Component ──────────────────────────────────
function SpinWheel({ segments, T, canSpin, onResult }) {
  const [spinning, setSpinning] = useState(false);
  const svgRef      = useRef(null);
  const startRotRef = useRef(0);
  const animRef     = useRef(null);
  const N     = segments.length || 20;
  const SLICE = 360 / N;

  useEffect(() => () => { if (animRef.current) cancelAnimationFrame(animRef.current); }, []);

  const doSpin = () => {
    if (spinning || !canSpin || !segments.length) return;
    setSpinning(true);

    const winner     = pickWeightedSegment(segments);
    const winnerIdx  = segments.findIndex(s => s.id === winner.id);
    const extraSpins = 5 + Math.floor(Math.random() * 4);
    const segCenter  = winnerIdx * SLICE + SLICE / 2;
    const targetRot  = (360 - (segCenter % 360)) % 360;
    const curNorm    = ((startRotRef.current % 360) + 360) % 360;
    let delta        = targetRot - curNorm;
    if (delta <= 0) delta += 360;
    const totalRot   = startRotRef.current + extraSpins * 360 + delta;
    const duration   = 4500 + Math.random() * 1000;
    const startTime  = performance.now();
    const fromRot    = startRotRef.current;
    const easeOut    = t => 1 - Math.pow(1 - t, 4);

    const animate = now => {
      const p   = Math.min((now - startTime) / duration, 1);
      const rot = fromRot + (totalRot - fromRot) * easeOut(p);
      if (svgRef.current) svgRef.current.style.transform = `rotate(${rot}deg)`;
      if (p < 1) {
        animRef.current = requestAnimationFrame(animate);
      } else {
        startRotRef.current = totalRot;
        setSpinning(false);
        onResult(winner);
      }
    };
    animRef.current = requestAnimationFrame(animate);
  };

  const cx = 150, cy = 150, r = 146;
  const slicePaths = segments.map((seg, i) => {
    const sa = (i * SLICE - 90) * (Math.PI / 180);
    const ea = ((i + 1) * SLICE - 90) * (Math.PI / 180);
    const x1 = cx + r * Math.cos(sa), y1 = cy + r * Math.sin(sa);
    const x2 = cx + r * Math.cos(ea), y2 = cy + r * Math.sin(ea);
    const ma = ((i + 0.5) * SLICE - 90) * (Math.PI / 180);
    const tr = r * 0.68;
    const tx = cx + tr * Math.cos(ma), ty = cy + tr * Math.sin(ma);
    const ta = (i + 0.5) * SLICE - 90;
    return (
      <g key={seg.id}>
        <path
          d={`M${cx},${cy} L${x1.toFixed(2)},${y1.toFixed(2)} A${r},${r} 0 0,1 ${x2.toFixed(2)},${y2.toFixed(2)} Z`}
          fill={i % 2 === 0 ? seg.color : seg.color + 'CC'}
          stroke={T.surface} strokeWidth="1.5"
        />
        <text
          x={tx.toFixed(2)} y={ty.toFixed(2)}
          textAnchor="middle" dominantBaseline="middle"
          transform={`rotate(${ta.toFixed(2)},${tx.toFixed(2)},${ty.toFixed(2)})`}
          fontSize={N > 15 ? '13' : '15'} fontFamily="DM Sans,sans-serif"
          style={{ pointerEvents:'none' }}
        >{seg.emoji}</text>
      </g>
    );
  });

  return (
    <div className="wheel-wrap">
      <div className="wheel-container">
        <div className="wheel-pointer" style={{ borderTopColor:T.accentDeep }}/>
        {canSpin && !spinning && (
          <div className="wheel-pulse" style={{ background:`radial-gradient(circle,${T.accent}22 0%,transparent 70%)` }}/>
        )}
        <svg ref={svgRef} width="300" height="300" viewBox="0 0 300 300" style={{ display:'block' }}>
          <defs><filter id="wsh"><feDropShadow dx="0" dy="3" stdDeviation="6" floodOpacity="0.12"/></filter></defs>
          <g filter="url(#wsh)">
            {slicePaths}
            <circle cx={cx} cy={cy} r="27" fill={T.surface} stroke={T.border} strokeWidth="2"/>
            <circle cx={cx} cy={cy} r="13" fill={T.accent}/>
          </g>
        </svg>
      </div>
      <button
        className="primary-btn"
        style={{ maxWidth:260, opacity:(!canSpin||spinning)?0.6:1 }}
        disabled={!canSpin || spinning}
        onClick={doSpin}
      >
        {spinning ? 'Spinning…' : '🎰  Spin the wheel'}
      </button>
    </div>
  );
}

function SpinResultCard({ seg, T, isNew }) {
  const isWin  = seg.type === 'win';
  const isBad  = seg.type === 'bad';
  const color  = isWin ? T.good : isBad ? T.danger : T.textMute;
  const badge  = isWin ? '🎉 You won!' : isBad ? '💸 Oof.' : '😐 Neutral';
  return (
    <div className="card spin-result" style={{ textAlign:'center' }}>
      <div className="spin-type-badge" style={{ background:`${color}15`, color }}>{badge}</div>
      <div style={{ fontSize:52, lineHeight:1, margin:'8px 0 6px' }}>{seg.emoji}</div>
      <div style={{ fontFamily:"'Playfair Display',Georgia,serif", fontSize:22, fontWeight:500, marginBottom:4 }}>{seg.label}</div>
      <div style={{ fontSize:13, color:T.textMute, lineHeight:1.5 }}>{seg.sub}</div>
      {isBad && (
        <div style={{ fontSize:12, color:T.textMute, marginTop:10 }}>IOU saved — tap <strong>Log it</strong> above when you're ready</div>
      )}
    </div>
  );
}

function IOUSection({ ious, myName, T, onRedeem }) {
  const pending = Object.entries(ious || {})
    .filter(([, i]) => !i.redeemedAt)
    .sort(([, a], [, b]) => new Date(b.createdAt) - new Date(a.createdAt));
  if (!pending.length) return null;

  return (
    <section className="card">
      <div className="card-head">
        <h3>Pending IOUs</h3>
        <span className="iou-count">{pending.length}</span>
      </div>
      <div className="activity-feed">
        {pending.map(([id, iou]) => {
          const isMyWin    = iou.spinner === myName && iou.type === 'win';
          const isMyBad    = iou.spinner === myName && iou.type === 'bad';
          const isTheirWin = iou.spinner !== myName && iou.type === 'win';

          let desc;
          if (isMyWin)    desc = 'You won — your spouse owes you this';
          if (isMyBad)    desc = 'You owe this';
          if (isTheirWin) desc = `${iou.spinner} won — you owe them this`;
          if (!isMyWin && !isMyBad && !isTheirWin) desc = `${iou.spinner} owes this`;

          const btnLabel = isMyBad ? 'Log it' : isTheirWin ? 'Mark given' : 'Mark done';

          return (
            <div key={id} className="iou-row">
              <div className="iou-emoji">{iou.emoji}</div>
              <div className="iou-mid">
                <div className="iou-label">{iou.label}</div>
                <div className="iou-desc">{desc}</div>
                <div className="iou-date">{relTime(iou.createdAt)}</div>
              </div>
              <button className={`iou-btn${isMyBad ? ' bad' : ''}`} onClick={() => onRedeem(id, iou)}>
                {btnLabel}
              </button>
            </div>
          );
        })}
      </div>
    </section>
  );
}

function SpinWheelView({ wheel, myName, settings, T, C, onSpinComplete, householdId, ious, onRedeemIOU }) {
  const [finalResult,    setFinalResult]    = useState(null);
  const [playAgainUsed,  setPlayAgainUsed]  = useState(false);
  const [playAgainFlash, setPlayAgainFlash] = useState(false);

  if (!householdId) return (
    <div className="stack fade-in">
      <div className="page-head"><h2>Daily Spin</h2><p>Connect a household to use the spin wheel.</p></div>
      <div className="empty"><div style={{ fontSize:36 }}>🔗</div><div className="empty-msg">No household</div><div className="empty-sub">Set up household sync in Settings to start spinning.</div></div>
    </div>
  );

  if (wheel === null) return (
    <div className="stack fade-in">
      <div className="page-head"><h2>Daily Spin</h2></div>
      <div style={{ textAlign:'center', padding:'60px 0', color:T.textMute, fontSize:13 }}>Loading…</div>
    </div>
  );

  const segments      = (wheel?.segments || DEFAULT_SEGMENTS).filter(s => s.enabled !== false);
  const spins         = wheel?.spins || {};
  const todayKey      = spinTodayKey();
  const myTodaySpin   = spins[todayKey]?.[myName];
  const alreadySpun   = !!myTodaySpin;
  const partnerName   = myName === settings.partner1 ? settings.partner2 : settings.partner1;
  const partnerSpin   = spins[todayKey]?.[partnerName];
  const myStreak      = calcSpinStreak(spins, myName);
  const partnerStreak = calcSpinStreak(spins, partnerName);

  const myHistory = Object.entries(spins)
    .filter(([, s]) => s[myName])
    .sort(([a], [b]) => b.localeCompare(a))
    .slice(0, 7)
    .map(([date, s]) => ({ date, ...s[myName] }));

  const canSpin = !alreadySpun && !finalResult;

  const handleResult = seg => {
    if (seg.label === 'Re-Spin' && !playAgainUsed) {
      setPlayAgainUsed(true);
      setPlayAgainFlash(true);
      setTimeout(() => setPlayAgainFlash(false), 1600);
      return;
    }
    setFinalResult(seg);
    onSpinComplete(seg, myName);
  };

  const resultToShow = alreadySpun ? myTodaySpin : finalResult;

  return (
    <div className="stack fade-in">
      <div className="page-head">
        <h2>Daily Spin</h2>
        <p>One spin a day · playing as <strong>{myName}</strong></p>
      </div>

      {(myStreak > 0 || partnerStreak > 0) && (
        <div style={{ display:'flex', justifyContent:'center', gap:8, flexWrap:'wrap' }}>
          {myStreak > 0 && <div className="spin-streak">🔥 {myName} · {myStreak}-day streak</div>}
          {partnerStreak > 0 && <div className="spin-streak" style={{ opacity:0.7 }}>🔥 {partnerName} · {partnerStreak}-day streak</div>}
        </div>
      )}

      <IOUSection ious={ious} myName={myName} T={T} onRedeem={(id, iou) => onRedeemIOU(id, iou, myName)}/>

      {playAgainFlash && (
        <div className="spin-play-again">🔄 Re-Spin!</div>
      )}

      {(!alreadySpun || finalResult) ? (
        <div style={{ position:'relative' }}>
          <div style={{ opacity:finalResult ? 0.15 : 1, transition:'opacity 0.8s ease', pointerEvents:finalResult ? 'none' : 'auto' }}>
            <SpinWheel segments={segments} T={T} canSpin={canSpin} onResult={handleResult}/>
          </div>
          {finalResult && (
            <div style={{ position:'absolute', top:0, left:0, right:0, bottom:0, display:'flex', alignItems:'center', justifyContent:'center', padding:'0 8px' }}>
              <SpinResultCard seg={finalResult} T={T} isNew={true}/>
            </div>
          )}
        </div>
      ) : myTodaySpin ? (
        <SpinResultCard seg={myTodaySpin} T={T} isNew={false}/>
      ) : null}

      {(alreadySpun || finalResult) && (
        <div className="card" style={{ textAlign:'center', padding:'14px 16px' }}>
          <div style={{ fontSize:12, color:T.textMute }}>⏰ Come back tomorrow for your next spin</div>
        </div>
      )}

      {partnerSpin && (
        <div className="spin-partner-card">
          <span style={{ fontSize:28 }}>{partnerSpin.emoji}</span>
          <div style={{ flex:1 }}>
            <div style={{ fontSize:10, textTransform:'uppercase', letterSpacing:'0.1em', color:T.textMute, fontWeight:500, marginBottom:2 }}>{partnerName}'s spin today</div>
            <div style={{ fontWeight:500, fontSize:14 }}>{partnerSpin.label}</div>
            <div style={{ fontSize:12, color:T.textMute }}>{partnerSpin.sub}</div>
          </div>
          <div style={{ fontSize:11, fontWeight:700, color: partnerSpin.type==='win'?T.good:partnerSpin.type==='bad'?T.danger:T.textMute, flexShrink:0 }}>
            {partnerSpin.type === 'win' ? 'Win' : partnerSpin.type === 'bad' ? 'Pay up' : '—'}
          </div>
        </div>
      )}

      {myHistory.length > 0 && (
        <div className="card">
          <div className="card-head"><h3>Your history</h3></div>
          <div className="activity-feed">
            {myHistory.map((entry, i) => {
              const c = entry.type==='win'?T.good:entry.type==='bad'?T.danger:T.textMute;
              return (
                <div key={i} className="feed-row" style={{ cursor:'default' }}>
                  <div className="spin-history-emoji" style={{ background:`${c}18` }}>{entry.emoji}</div>
                  <div className="feed-mid">
                    <div className="feed-line">
                      <span className="feed-who">{entry.label}</span>
                      <span className="feed-action"> · {entry.sub}</span>
                    </div>
                    <div className="feed-date">{new Date(entry.date + 'T12:00:00').toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'})}</div>
                  </div>
                  <div style={{ fontSize:10, fontWeight:700, color:c, flexShrink:0 }}>
                    {entry.type==='win'?'Win':entry.type==='bad'?'Pay up':'—'}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}
