// Right-rail panel — severity score, drift indicator, current-moment
// recommendation (traffic light), and personalised advice from Claude.

const { useState: useStateAd, useEffect: useEffectAd, useMemo: useMemoAd } = React;
const { fmtHM, hmToMin, tzLocalParts } = window.JL;

// Determine what the user should be doing RIGHT NOW based on destination time
// and the selected day's plan.
function currentRecommendation(day, destTz) {
  const local = tzLocalParts(destTz, new Date());
  const nowMin = local.hour * 60 + local.minute;
  const inWindow = (start, end) => {
    const a = hmToMin(start), b = hmToMin(end);
    if (a <= b) return nowMin >= a && nowMin <= b;
    return nowMin >= a || nowMin <= b; // wraps midnight
  };
  // Priority: sleep > meal > light > caffeine > rest
  if (inWindow(day.sleep.start, day.sleep.end)) {
    return { level: 'red', icon: '💤', title: 'Sleep window',
      detail: `Your body is in its sleep period until ${fmtHM(day.sleep.end)}. Eyes closed, no screens, no light.` };
  }
  // Within 90 min of sleep start
  const sleepStartMin = hmToMin(day.sleep.start);
  const minToSleep = ((sleepStartMin - nowMin + 1440) % 1440);
  if (minToSleep < 90) {
    return { level: 'amber', icon: '🌙', title: 'Wind down',
      detail: `Bedtime in ${minToSleep} min. Dim lights, no screens, avoid food.` };
  }
  if (day.melatonin) {
    const melMin = hmToMin(day.melatonin.time);
    const diff = (melMin - nowMin + 1440) % 1440;
    if (diff < 30) return { level: 'amber', icon: '💊', title: 'Melatonin window',
      detail: `Take ${day.melatonin.dose} of melatonin now (about 30 min before bed).` };
  }
  if (day.light && nowMin >= hmToMin(day.light.start) && nowMin <= hmToMin(day.light.end)) {
    return { level: 'green', icon: '☀️', title: day.light.kind,
      detail: `Get bright outdoor light until ${fmtHM(day.light.end)} — this is the most powerful jet lag treatment.` };
  }
  // Near meals
  for (const [k, t] of Object.entries(day.meals)) {
    const diff = Math.abs(hmToMin(t) - nowMin);
    if (diff < 30) {
      const icon = k === 'breakfast' ? '🍳' : k === 'lunch' ? '🥗' : '🍽️';
      return { level: 'green', icon, title: `${k[0].toUpperCase()}${k.slice(1)} time`,
        detail: `Eat on destination schedule — this entrains your circadian rhythm.` };
    }
  }
  if (day.caffeine && nowMin > hmToMin(day.caffeine.end)) {
    return { level: 'amber', icon: '☕', title: 'No more caffeine',
      detail: `Caffeine cutoff was at ${fmtHM(day.caffeine.end)}. Switch to water or herbal tea.` };
  }
  return { level: 'green', icon: '✨', title: 'On track',
     detail: 'Stay awake, keep moving, hydrate. Sleep on destination schedule tonight.' };
}

function Recommendation({ plan, selectedIdx }) {
  const [now, setNow] = useStateAd(Date.now());
  useEffectAd(() => {
    const id = setInterval(() => setNow(Date.now()), 60000);
    return () => clearInterval(id);
  }, []);
  if (!plan) return null;
  const day = plan.days[selectedIdx];
  const rec = useMemoAd(() => currentRecommendation(day, plan.destTz), [day, plan.destTz, now]);

  const colors = {
    red:   { bg: 'rgba(255, 80, 110, 0.12)', border: '#ff506e', glow: 'rgba(255, 80, 110, 0.35)' },
    amber: { bg: 'rgba(255, 180, 70, 0.12)', border: '#ffb446', glow: 'rgba(255, 180, 70, 0.35)' },
    green: { bg: 'rgba(125, 230, 150, 0.12)', border: '#7de696', glow: 'rgba(125, 230, 150, 0.3)' },
  }[rec.level];

  return (
    <div className="jl-pop" key={rec.title} style={{
      display: 'flex', flexDirection: 'column', gap: 6,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 12, height: 12, borderRadius: '50%', background: colors.border,
          boxShadow: `0 0 8px ${colors.border}`,
          animation: 'jlPulse 2s ease-in-out infinite',
        }} />
        <div style={{ fontSize: 10, letterSpacing: '0.3em', color: colors.border,
          fontWeight: 700, textTransform: 'uppercase' }}>
          Do this now
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <span style={{ fontSize: 28 }}>{rec.icon}</span>
        <span style={{ fontSize: 18, color: '#fafafa', fontWeight: 600 }}>{rec.title}</span>
      </div>
      <div style={{ fontSize: 13, color: 'rgba(255,255,255,0.75)', lineHeight: 1.5 }}>
        {rec.detail}
      </div>
    </div>
  );
}

// SeverityScore — big number with a gauge
function SeverityScore({ plan }) {
  if (!plan) return null;
  const { severity, deltaHours, direction, recoveryDays } = plan;
  const color = severity <= 3 ? '#7de696' : severity <= 6 ? '#ffd166' : severity <= 8 ? '#ff9b50' : '#ff506e';
  const pct = severity / 10;
  const angle = pct * 270;

  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '100px 1fr', gap: 16, alignItems: 'center',
    }}>
      {/* gauge */}
      <div style={{ position: 'relative', width: 100, height: 100 }}>
        <svg viewBox="0 0 100 100" style={{ width: '100%', height: '100%' }}>
          {/* background ring */}
          <circle cx="50" cy="50" r="40" fill="none"
            stroke="rgba(255,255,255,0.1)" strokeWidth="8"
            strokeDasharray={`${270 * Math.PI * 40 / 180} 1000`}
            transform="rotate(135 50 50)" strokeLinecap="round" />
          {/* fill */}
          <circle cx="50" cy="50" r="40" fill="none"
            stroke={color} strokeWidth="8"
            strokeDasharray={`${angle * Math.PI * 40 / 180} 1000`}
            transform="rotate(135 50 50)" strokeLinecap="round"
            style={{
              filter: `drop-shadow(0 0 6px ${color}aa)`,
              transition: 'stroke-dasharray 1s cubic-bezier(0.16, 1, 0.3, 1)',
            }} />
        </svg>
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexDirection: 'column',
        }}>
          <div style={{ fontSize: 28, fontWeight: 200, color: '#fff',
            fontVariantNumeric: 'tabular-nums', letterSpacing: '-1px' }}>
            {severity.toFixed(1)}
          </div>
          <div style={{ fontSize: 8, color: 'rgba(255,255,255,0.55)', letterSpacing: '0.2em' }}>
            /10
          </div>
        </div>
      </div>
      <div>
        <div style={{ fontSize: 10, letterSpacing: '0.3em', color: 'rgba(255,255,255,0.55)',
          fontWeight: 700, marginBottom: 4 }}>
          JET LAG SEVERITY
        </div>
        <div style={{ fontSize: 15, color: '#fafafa', fontWeight: 600, marginBottom: 6 }}>
          {Math.abs(deltaHours).toFixed(1)}h {direction === 'east' ? 'eastward' : direction === 'west' ? 'westward' : 'no shift'}
        </div>
        <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.6)', lineHeight: 1.4 }}>
          Expected to recover in <strong style={{ color: '#fff' }}>{recoveryDays}d</strong>
          {direction === 'east' && ' — eastward travel is harder because the body resists shifting earlier.'}
          {direction === 'west' && ' — westward is easier; the body adapts faster when staying up later.'}
        </div>
      </div>
    </div>
  );
}

// Personalised advice from Claude (one paragraph, cached per trip)
function ClaudeAdvice({ plan, chronotype }) {
  const [text, setText] = useStateAd('');
  const [loading, setLoading] = useStateAd(false);
  const cacheKeyRef = React.useRef('');

  // Build a stable cache key so we don't re-call on every render
  const cacheKey = useMemoAd(() => {
    if (!plan) return '';
    return `${plan.originTz}|${plan.destTz}|${plan.deltaHours.toFixed(1)}|${plan.tripLengthDays}|${chronotype}`;
  }, [plan, chronotype]);

  useEffectAd(() => {
    if (!plan || !cacheKey || cacheKey === cacheKeyRef.current) return;
    cacheKeyRef.current = cacheKey;
    setLoading(true);
    setText('');

    const prompt = `You are a friendly jet lag coach. Write ONE concise, practical paragraph (≤60 words) of personalised advice for a traveler.
Trip details:
- From: ${plan.originTz}
- To: ${plan.destTz}
- Timezone shift: ${plan.deltaHours.toFixed(1)} hours (${plan.direction})
- Trip length: ${plan.tripLengthDays} days
- Chronotype: ${chronotype}
- Severity: ${plan.severity.toFixed(1)}/10
- Recovery: ${plan.recoveryDays} days

Give one specific actionable tip tailored to this trip. No headings, no lists. Conversational tone. Start directly with the advice, don't introduce yourself.`;

    window.claude.complete(prompt)
      .then(r => setText(r.trim()))
      .catch(() => setText('Stay hydrated, get bright morning light at your destination, and avoid napping for more than 20 minutes on arrival day.'))
      .finally(() => setLoading(false));
  }, [cacheKey, plan, chronotype]);

  if (!plan) return null;
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
        <div style={{
          width: 18, height: 18, borderRadius: '50%',
          background: 'radial-gradient(circle at 30% 30%, #fff, #ffd166)',
          boxShadow: '0 0 10px rgba(255, 209, 102, 0.6)',
          animation: loading ? 'jlSpin 1.5s linear infinite' : 'none',
        }} />
        <div style={{ fontSize: 10, letterSpacing: '0.3em', color: 'rgba(255,255,255,0.55)',
          fontWeight: 700 }}>
          PERSONALISED ADVICE
        </div>
      </div>
      {loading && !text && (
        <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.4)', fontStyle: 'italic' }}>
          Composing your plan…
        </div>
      )}
      {text && (
        <div className="jl-boot" style={{
          fontSize: 13, color: 'rgba(255,255,255,0.85)', lineHeight: 1.55,
        }}>
          {text}
        </div>
      )}
    </div>
  );
}

window.Recommendation = Recommendation;
window.SeverityScore = SeverityScore;
window.ClaudeAdvice = ClaudeAdvice;
