// prizewheel.jsx — Fire Lingo promotion prize wheel.
//
// Replaces the left (member) panel of the translation screen while a promotion
// is running. The employee sidebar — status card, Finish serving member, mode
// picker — stays untouched, so the "select language → serve member → finish"
// flow is never broken.
//
// Copy is lifted verbatim from PrizeWheel.swift so the redesign stays faithful
// to what members read in production today.

// Segment palette — brand-derived instead of the saturated rainbow. Alternating
// tints of the active brand keep the wheel readable and on-system, while the
// prize and retry segments stay high-contrast so they're findable at a glance.
const WHEEL_TINTS = [
  'var(--td-blue-300)', 'var(--td-blue)', 'var(--td-blue-600)',
  'var(--td-blue-400)', 'var(--td-blue-200)', 'var(--td-blue-500)',
];

// Localized member-facing copy. English is always shown beneath the native line,
// mirroring the bilingual popups in the current build.
const WHEEL_COPY = {
  en:      { spin: 'Tap to spin',        again: 'You won another spin!\nPlease spin the wheel again.',       lose: 'Sorry, no prize. Hope you had fun!' },
  'es':    { spin: 'Toca para girar',    again: '¡Has ganado otra ronda!\nVuelve a girar la ruleta.',        lose: 'Lo sentimos, no ganaste premio.\n¡Esperamos que te hayas divertido!' },
  'ko':    { spin: '탭하여 돌리기',        again: '한 번 더 돌릴 수 있어요!\n휠을 다시 돌려주세요.',                lose: '아쉽지만 당첨되지 않았어요.\n즐거우셨길 바랍니다!' },
  'fr':    { spin: 'Touchez pour tourner', again: 'Vous avez gagné un tour !\nFaites tourner la roue à nouveau.', lose: 'Désolé, pas de prix.\nNous espérons que vous vous êtes amusé !' },
  'zh':    { spin: '点击转动',             again: '您赢得了再转一次的机会！\n请再次转动转盘。',                    lose: '很遗憾，没有中奖。\n希望您玩得开心！' },
  'ht':    { spin: 'Peze pou vire',       again: 'Ou genyen yon lòt tou!\nVire wou a ankò.',                  lose: 'Nou regrèt, ou pa genyen.\nNou espere ou te amize w!' },
  'sw':    { spin: 'Gusa kuzungusha',     again: 'Umeshinda zamu nyingine!\nZungusha gurudumu tena.',         lose: 'Samahani, hukushinda zawadi.\nTunatumai ulifurahia!' },
  'pt-BR': { spin: 'Toque para girar',    again: 'Você ganhou outra rodada!\nGire a roleta novamente.',       lose: 'Desculpe, sem prêmio.\nEsperamos que tenha se divertido!' },
  'pt-PT': { spin: 'Toque para girar',    again: 'Ganhou outra rodada!\nRode a roleta novamente.',            lose: 'Lamentamos, sem prémio.\nEsperamos que se tenha divertido!' },
  'vi':    { spin: 'Chạm để quay',        again: 'Bạn được quay thêm lượt nữa!\nHãy quay lại vòng quay.',     lose: 'Rất tiếc, bạn chưa trúng thưởng.\nHy vọng bạn đã vui!' },
  'ar':    { spin: 'اضغط للدوران',        again: '!لقد ربحت دورة أخرى\n.أدر العجلة مرة أخرى',                  lose: '.عذراً، لم تربح جائزة\n!نأمل أنك استمتعت' },
  'prs':   { spin: 'برای چرخاندن ضربه بزنید', again: '!شما یک چرخش دیگر بردید\n.لطفاً چرخ را دوباره بچرخانید', lose: '.متأسفیم، جایزه‌ای نبود\n!امیدواریم لذت برده باشید' },
  'ru':    { spin: 'Нажмите, чтобы крутить', again: 'Вы выиграли ещё одну попытку!\nКрутите колесо снова.',   lose: 'К сожалению, приза нет.\nНадеемся, вам понравилось!' },
  'uk':    { spin: 'Натисніть, щоб крутити', again: 'Ви виграли ще одну спробу!\nКрутіть колесо знову.',      lose: 'На жаль, призу немає.\nСподіваємось, вам сподобалось!' },
  'ro':    { spin: 'Atinge pentru a învârti', again: 'Ai câștigat încă o rotire!\nÎnvârte roata din nou.',    lose: 'Ne pare rău, fără premiu.\nSperăm că te-ai distrat!' },
  'so':    { spin: 'Taabo si aad u wareejiso', again: 'Waxaad ku guulaysatay wareeg kale!\nFadlan mar kale wareeji.', lose: 'Waan ka xunnahay, abaalmarin ma jirto.\nWaxaan rajaynaynaa inaad ku raaxaysatay!' },
};

function wheelCopy(code) {
  return { ...WHEEL_COPY.en, ...(WHEEL_COPY[code] || {}) };
}

// ---------------------------------------------------------------- wheel shape

function WheelShape({ segments, prizeIndex, retryIndices, size }) {
  const r = size / 2;
  const step = 360 / segments;
  const slice = (i) => {
    const a0 = (i * step - 90) * Math.PI / 180;
    const a1 = ((i + 1) * step - 90) * Math.PI / 180;
    const x0 = r + r * Math.cos(a0), y0 = r + r * Math.sin(a0);
    const x1 = r + r * Math.cos(a1), y1 = r + r * Math.sin(a1);
    return `M ${r} ${r} L ${x0} ${y0} A ${r} ${r} 0 0 1 ${x1} ${y1} Z`;
  };

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>
      {Array.from({ length: segments }).map((_, i) => {
        const isPrize = i === prizeIndex;
        const isRetry = retryIndices.includes(i);
        const fill = isPrize ? '#fff'
                   : isRetry ? 'var(--td-navy)'
                   : WHEEL_TINTS[i % WHEEL_TINTS.length];
        const mid = (i * step + step / 2 - 90);
        const labelR = r * 0.66;
        const lx = r + labelR * Math.cos(mid * Math.PI / 180);
        const ly = r + labelR * Math.sin(mid * Math.PI / 180);
        // Keep labels upright-ish: flip any that would read upside down.
        const flip = mid > 90 && mid < 270;
        return (
          <g key={i}>
            <path d={slice(i)} fill={fill} stroke="rgba(255,255,255,0.35)" strokeWidth="1.5" />
            {(isPrize || isRetry) && (
              <text
                x={lx} y={ly}
                transform={`rotate(${flip ? mid + 180 : mid} ${lx} ${ly})`}
                textAnchor="middle" dominantBaseline="middle"
                fontFamily="var(--font-display)"
                fontSize={isPrize ? 24 : 17}
                fontWeight={isPrize ? 900 : 700}
                fill={isPrize ? 'var(--td-navy)' : '#fff'}
                letterSpacing={isPrize ? '0.02em' : '0'}
              >{isPrize ? 'Prize' : 'Spin again'}</text>
            )}
          </g>
        );
      })}
      <circle cx={r} cy={r} r={r * 0.085} fill="#fff" stroke="var(--td-navy)" strokeWidth="3" />
    </svg>
  );
}

// ------------------------------------------------------------- result overlay

function ResultCard({ kind, lang, copy, nativeFont, prizeTitle, prizeBody }) {
  const isWin = kind === 'win';
  const accent = isWin ? '#2FB84C' : kind === 'again' ? 'var(--td-orange)' : 'var(--td-slate-500)';
  const icon = isWin
    ? <path d="M20 6 9 17l-5-5" />
    : kind === 'again'
    ? <><path d="M21 2v6h-6" /><path d="M3 12a9 9 0 0 1 15-6.7L21 8" /><path d="M3 22v-6h6" /><path d="M21 12a9 9 0 0 1-15 6.7L3 16" /></>
    : <><circle cx="12" cy="12" r="10" /><path d="M8 15s1.5-2 4-2 4 2 4 2" /><path d="M9 9h.01M15 9h.01" /></>;

  const nativeText = isWin ? prizeTitle : kind === 'again' ? copy.again : copy.lose;
  const englishText = isWin
    ? 'You won a $25 gift card!'
    : kind === 'again'
    ? 'You won another spin!\nPlease spin the wheel again.'
    : 'Sorry, no prize. Hope you had fun!';

  return (
    <div style={{
      width: '100%', maxWidth: 560,
      background: '#fff', borderRadius: 'var(--radius-xl)',
      boxShadow: 'var(--shadow-xl)', overflow: 'hidden',
      animation: 'fl-fade-in 320ms var(--ease-out) both',
    }}>
      <div style={{
        height: 6, background: accent,
      }} />
      <div style={{ padding: '28px 32px 30px', textAlign: 'center' }}>
        <div style={{
          width: 60, height: 60, borderRadius: 999, margin: '0 auto 18px',
          background: isWin ? 'rgba(47,184,76,0.12)' : kind === 'again' ? 'rgba(207,99,40,0.12)' : 'var(--td-slate-100)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          {/* Winning state is the one sanctioned exception to the no-emoji rule —
             a celebration reads instantly across every language on the tablet. */}
          {isWin ? (
            <span style={{ fontSize: 34, lineHeight: 1 }} role="img" aria-label="Celebration">🎉</span>
          ) : (
            <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke={accent}
              strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">{icon}</svg>
          )}
        </div>

        <div style={{
          fontFamily: nativeFont, fontSize: 30, fontWeight: 800,
          color: 'var(--td-navy)', lineHeight: 1.28, whiteSpace: 'pre-line',
          letterSpacing: lang.script === 'cjk' ? 0 : '-0.015em',
          direction: lang.script === 'rtl' ? 'rtl' : 'ltr',
        }}>{isWin ? `🎊 ${nativeText} 🎊` : nativeText}</div>

        <div style={{
          marginTop: 12, paddingTop: 14, borderTop: '1px solid var(--divider)',
          fontFamily: 'var(--font-sans)', fontSize: 17, fontWeight: 500,
          color: 'var(--fg2)', lineHeight: 1.45, whiteSpace: 'pre-line',
        }}>{isWin ? `🎁 ${englishText}` : englishText}</div>

        {isWin && (
          <div style={{
            marginTop: 18, padding: '14px 18px',
            background: 'var(--td-blue-50)', borderRadius: 'var(--radius-md)',
            fontFamily: 'var(--font-sans)', fontSize: 15, fontWeight: 600,
            color: 'var(--td-navy)', lineHeight: 1.4,
          }}>{prizeBody}</div>
        )}
      </div>
    </div>
  );
}

// ------------------------------------------------------------------ main view

function PrizeWheelPanel({ lang, nativeFont, onClose, hasPrizes = true, forcedOutcome = null,
                          memberDown, memberUp, memberPhase, employeePhase, memberLevel, btn }) {
  const copy = wheelCopy(lang.code);

  const SEGMENTS = 15;
  const PRIZE_INDEX = 0;
  const RETRY_INDICES = [5, 10];

  const [angle, setAngle] = React.useState(-(360 / SEGMENTS) / 2);
  const [spinning, setSpinning] = React.useState(false);
  const [result, setResult] = React.useState(null);   // 'again' | 'win' | 'lose'
  const [spinCount, setSpinCount] = React.useState(0);

  const size = 540;

  const spin = () => {
    if (spinning || result === 'win' || result === 'lose' || !hasPrizes) return;
    setResult(null);
    setSpinning(true);

    // Decide the outcome, then land the wheel on the matching segment.
    const outcome = forcedOutcome
      || (spinCount === 0 ? 'again' : spinCount === 1 ? 'win' : 'lose');
    const landIndex = outcome === 'win' ? PRIZE_INDEX
                    : outcome === 'again' ? RETRY_INDICES[spinCount % RETRY_INDICES.length]
                    : 3;

    const step = 360 / SEGMENTS;
    const target = -(landIndex * step + step / 2);
    const turns = 5 * 360;
    const next = Math.floor(angle / 360) * 360 + turns + target;

    setAngle(next);
    setTimeout(() => {
      setSpinning(false);
      setSpinCount(c => c + 1);
      setResult(outcome);
    }, 3400);
  };

  const canSpin = !spinning && hasPrizes && (result === null || result === 'again');

  // Mic state mirrors the turn-based screen so the sidebar status card lights up
  // with processing / translating exactly as it does in a normal conversation.
  const memberSpeaking = memberPhase === 'listening' || employeePhase === 'listening';
  const micBusy = (memberPhase && memberPhase !== 'idle' && memberPhase !== 'listening')
               || (employeePhase && employeePhase !== 'idle' && employeePhase !== 'listening');

  // ── No prizes configured: surface the error instead of the wheel ──────────
  if (!hasPrizes) {
    return (
      <div style={{
        flex: 1.4, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center',
        padding: '32px 48px', position: 'relative', zIndex: 1, gap: 22,
      }}>
        <div style={{
          width: 72, height: 72, borderRadius: 999,
          background: 'rgba(255,255,255,0.10)',
          border: '1px solid rgba(255,255,255,0.18)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="#FFD4B7"
            strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
            <path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
            <path d="M12 9v4M12 17h.01" />
          </svg>
        </div>
        <div style={{ textAlign: 'center', maxWidth: 460 }}>
          <div style={{
            fontFamily: 'var(--font-display)', fontSize: 30, fontWeight: 800,
            color: '#fff', letterSpacing: '-0.02em', lineHeight: 1.2,
          }}>No prizes available</div>
          <div style={{
            marginTop: 10, fontFamily: 'var(--font-sans)', fontSize: 16,
            color: 'rgba(255,255,255,0.72)', lineHeight: 1.5,
          }}>All prizes for this promotion have been claimed or no promotion has been set. Close this and continue the conversation as normal.</div>
        </div>
        <button onClick={onClose} className="fl-secondary-btn" style={{ minHeight: 52, padding: '0 28px', fontSize: 15 }}>
          Back to conversation
        </button>
      </div>
    );
  }

  return (
    <div style={{
      flex: 1.4, display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      padding: '24px 40px 28px', position: 'relative', zIndex: 1,
      minHeight: 0,
    }}>
      {/* Promotion eyebrow + close */}
      <div style={{
        position: 'absolute', top: 22, left: 40, right: 40,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 9,
          padding: '6px 13px 6px 9px',
          background: 'rgba(255,255,255,0.10)',
          border: '1px solid rgba(255,255,255,0.18)',
          borderRadius: 'var(--radius-pill)',
        }}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="var(--td-orange)" strokeWidth="2.2">
            <circle cx="12" cy="12" r="9" />
            <path d="M12 3v18M3 12h18M5.6 5.6l12.8 12.8M18.4 5.6 5.6 18.4" strokeWidth="1.4" />
          </svg>
          <span style={{
            fontFamily: 'var(--font-sans)', fontSize: 10.5, fontWeight: 700,
            textTransform: 'uppercase', letterSpacing: '0.14em', color: '#fff',
          }}>Promotion</span>
        </div>

        <button onClick={onClose} aria-label="Close promotion" style={{
          width: 38, height: 38, borderRadius: 999,
          background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.16)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', WebkitTapHighlightColor: 'transparent',
        }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.85)" strokeWidth="2.4" strokeLinecap="round">
            <path d="M18 6 6 18M6 6l12 12" />
          </svg>
        </button>
      </div>

      {/* Result overlay replaces the wheel on a terminal outcome */}
      {(result === 'win' || result === 'lose') ? (
        <div style={{
          display: 'flex', flexDirection: 'column', alignItems: 'center',
          gap: 18, width: '100%', minHeight: 0,
        }}>
          <ResultCard
            kind={result}
            lang={lang}
            copy={copy}
            nativeFont={nativeFont}
            prizeTitle="¡Ganaste una tarjeta de regalo de $25!"
            prizeBody="Team member: please speak to the branch manager to receive the gift card."
          />

          {/* Translation mic — the winner keeps talking to the employee right
             here, same tap-and-hold → processing → translating lifecycle as the
             normal turn-based screen (matches RecordButton in PrizeWheel.swift). */}
          <div style={{ position: 'relative', width: 168, height: 168, flexShrink: 0 }}>
            {memberSpeaking && (
              <>
                <div style={{
                  position: 'absolute', inset: 0, borderRadius: 9999,
                  background: 'radial-gradient(circle, rgba(207,99,40,0.35) 45%, rgba(207,99,40,0) 58%)',
                  transform: `scale(${1 + (memberLevel || 0) * 0.08})`,
                  transition: 'transform 120ms var(--ease-out)',
                  pointerEvents: 'none',
                }} />
                <div style={{
                  position: 'absolute', inset: 5, borderRadius: 9999,
                  border: '2px solid rgba(255,212,183,0.55)',
                  transform: `scale(${1 + (memberLevel || 0) * 0.05})`,
                  transition: 'transform 90ms var(--ease-out)',
                  pointerEvents: 'none',
                }} />
              </>
            )}
            <button
              onPointerDown={memberDown}
              onPointerUp={memberUp}
              onPointerLeave={memberUp}
              onPointerCancel={memberUp}
              disabled={micBusy}
              aria-label={memberSpeaking ? 'Release to translate' : 'Hold to speak'}
              style={{
                position: 'absolute', inset: 0, borderRadius: 9999, border: 'none',
                cursor: micBusy ? 'not-allowed' : 'pointer',
                background: memberSpeaking
                  ? 'radial-gradient(circle at 30% 30%, #e27a3f 0%, var(--td-orange) 60%, #a64d1e 100%)'
                  : 'radial-gradient(circle at 30% 30%, var(--td-blue-300) 0%, var(--td-blue) 55%, var(--td-blue-600) 100%)',
                boxShadow: memberSpeaking
                  ? '0 14px 34px rgba(207,99,40,0.45), inset 0 -5px 12px rgba(0,0,0,0.18), inset 0 3px 8px rgba(255,255,255,0.25)'
                  : '0 14px 34px rgba(70,137,200,0.35), inset 0 -5px 12px rgba(0,0,0,0.18), inset 0 3px 8px rgba(255,255,255,0.25)',
                transform: memberSpeaking ? 'translateY(2px)' : 'translateY(0)',
                transition: 'background 200ms var(--ease-out), box-shadow 200ms var(--ease-out), transform 120ms var(--ease-out)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                WebkitTapHighlightColor: 'transparent', touchAction: 'none', outline: 'none',
                opacity: micBusy ? 0.55 : 1,
              }}>
              <svg width="56" height="56" viewBox="0 0 24 24" fill="none"
                stroke="#fff" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"
                style={{ filter: 'drop-shadow(0 3px 6px rgba(0,0,0,0.3))' }}>
                <rect x="9" y="2" width="6" height="12" rx="3" fill="rgba(255,255,255,0.22)" />
                <path d="M5 11a7 7 0 0 0 14 0" />
                <path d="M12 18v3M9 21h6" />
              </svg>
            </button>
          </div>

          <div style={{
            fontFamily: nativeFont, fontSize: 17, fontWeight: 700,
            color: memberSpeaking ? '#FFD4B7' : 'rgba(255,255,255,0.88)',
            transition: 'color 200ms var(--ease-out)', textAlign: 'center',
            direction: lang.script === 'rtl' ? 'rtl' : 'ltr',
          }}>
            {btn ? (memberSpeaking ? btn.release : btn.hold) : (memberSpeaking ? 'Release' : 'Hold to speak')}
          </div>
        </div>
      ) : (
        <>
          {/* Wheel + pointer */}
          <div style={{ position: 'relative', width: size, height: size, flexShrink: 0 }}>
            <div style={{
              width: '100%', height: '100%', borderRadius: 999,
              boxShadow: '0 24px 60px rgba(0,0,0,0.34), 0 0 0 8px rgba(255,255,255,0.10)',
              transform: `rotate(${angle}deg)`,
              transition: spinning ? 'transform 3.4s cubic-bezier(0.16, 1, 0.24, 1)' : 'none',
              cursor: canSpin ? 'pointer' : 'default',
            }}
              onClick={spin}
              role="button"
              aria-label="Spin the prize wheel">
              <WheelShape segments={SEGMENTS} prizeIndex={PRIZE_INDEX} retryIndices={RETRY_INDICES} size={size} />
            </div>

            {/* Pointer — sits at 12 o'clock, brand orange */}
            <div style={{
              position: 'absolute', top: -14, left: '50%', transform: 'translateX(-50%)',
              filter: 'drop-shadow(0 3px 6px rgba(0,0,0,0.35))', pointerEvents: 'none',
            }}>
              <svg width="34" height="30" viewBox="0 0 34 30">
                <path d="M17 30 L3 2 A2 2 0 0 1 5 0 L29 0 A2 2 0 0 1 31 2 Z"
                  fill="var(--td-orange)" stroke="#fff" strokeWidth="2.5" strokeLinejoin="round" />
              </svg>
            </div>
          </div>

          {/* Prompt / retry message */}
          <div style={{ marginTop: 22, textAlign: 'center', minHeight: 96 }}>
            {result === 'again' ? (
              <div style={{
                display: 'inline-block', padding: '14px 26px',
                background: 'rgba(207,99,40,0.16)', border: '1px solid rgba(207,99,40,0.42)',
                borderRadius: 'var(--radius-lg)',
                animation: 'fl-fade-in 300ms var(--ease-out) both',
              }}>
                <div style={{
                  fontFamily: nativeFont, fontSize: 22, fontWeight: 800,
                  color: '#FFD4B7', lineHeight: 1.3, whiteSpace: 'pre-line',
                  direction: lang.script === 'rtl' ? 'rtl' : 'ltr',
                }}>{copy.again}</div>
                <div style={{
                  marginTop: 6, fontFamily: 'var(--font-sans)', fontSize: 14, fontWeight: 500,
                  color: 'rgba(255,255,255,0.72)', lineHeight: 1.4, whiteSpace: 'pre-line',
                }}>You won another spin!{'\n'}Please spin the wheel again.</div>
              </div>
            ) : (
              <>
                <div style={{
                  fontFamily: nativeFont, fontSize: 26, fontWeight: 800,
                  color: '#fff', letterSpacing: lang.script === 'cjk' ? 0 : '-0.01em',
                  direction: lang.script === 'rtl' ? 'rtl' : 'ltr',
                  opacity: spinning ? 0.45 : 1, transition: 'opacity 200ms var(--ease-out)',
                }}>{copy.spin}</div>
                <div style={{
                  marginTop: 5, fontFamily: 'var(--font-sans)', fontSize: 15, fontWeight: 500,
                  color: 'rgba(255,255,255,0.62)',
                  opacity: spinning ? 0.45 : 1, transition: 'opacity 200ms var(--ease-out)',
                }}>{spinning ? 'Spinning…' : 'Tap the wheel to spin'}</div>
              </>
            )}
          </div>
        </>
      )}
    </div>
  );
}

Object.assign(window, { PrizeWheelPanel });
