// TODAY view — mission control + today's tasks + streak + hours + energy + digest + missed-day banner

function TodayView() {
  const { state, update } = useStore();
  const data = window.PLAN_DATA;
  const TODAY = useToday();
  const today = fmtDate(TODAY);
  const todayEntry = data.calendar.find(c => c.date === today);
  const phase = currentPhaseFor(TODAY);

  // Countdown to interview launch
  const launchDate = parseDate(data.meta.interviewLaunch);
  const daysToLaunch = daysBetween(TODAY, launchDate);

  // Sprint progress
  const sprintStart = parseDate(data.meta.sprintStart);
  const sprintEnd = parseDate(data.meta.sprintEnd);
  const sprintTotal = daysBetween(sprintStart, sprintEnd) + 1;
  const rawElapsed = daysBetween(sprintStart, TODAY) + 1;
  const sprintElapsed = Math.max(0, Math.min(sprintTotal, rawElapsed));
  const sprintPct = (sprintElapsed / sprintTotal) * 100;

  // Phase progress
  const phaseStart = parseDate(phase.start);
  const phaseEnd = parseDate(phase.end);
  const phaseTotal = daysBetween(phaseStart, phaseEnd) + 1;
  const phaseElapsed = Math.max(0, Math.min(phaseTotal, daysBetween(phaseStart, TODAY) + 1));
  const phasePct = Math.min(100, (phaseElapsed / phaseTotal) * 100);

  // Total tasks done
  const totalDone = Object.values(state.days).filter(d => d?.done).length;

  // Upcoming preview
  const todayIdx = data.calendar.findIndex(c => c.date === today);
  const upcoming = data.calendar.slice(todayIdx === -1 ? 0 : todayIdx, (todayIdx === -1 ? 0 : todayIdx) + 7);

  // Today's per-day state
  const dayState = state.days[today] || {};
  const setDay = (patch) => {
    update(prev => ({
      ...prev,
      days: { ...prev.days, [today]: { ...prev.days[today], ...patch } }
    }));
  };

  // ---- Feature 3: streak (active day = done OR note OR actualHours > 0) ----
  function isActive(d) {
    return !!(d && (d.done || (d.note && d.note.trim()) || (parseFloat(d.actualHours) > 0)));
  }
  const streak = (() => {
    let s = 0;
    for (let i = 0; i < 365; i++) {
      const dt = new Date(TODAY);
      dt.setDate(dt.getDate() - i);
      const k = fmtDate(dt);
      if (isActive(state.days[k])) s++;
      else if (i === 0) continue; // today not yet logged is OK
      else break;
    }
    return s;
  })();

  // ---- Feature 2: hours-this-week vs planned ----
  function startOfWeek(d) {
    const out = new Date(d);
    while (out.getDay() !== 1) out.setDate(out.getDate() - 1); // Monday
    return out;
  }
  const weekStart = startOfWeek(TODAY);
  const weekDays = Array.from({length: 7}, (_, i) => {
    const dt = new Date(weekStart); dt.setDate(dt.getDate() + i);
    return fmtDate(dt);
  });
  const plannedHrs = weekDays.reduce((sum, k) => {
    const e = data.calendar.find(c => c.date === k);
    return sum + (e?.hours || 0);
  }, 0);
  const actualHrs = weekDays.reduce((sum, k) => sum + (parseFloat(state.days[k]?.actualHours) || 0), 0);
  const hoursPctMatch = plannedHrs ? Math.round((actualHrs / plannedHrs) * 100) : 0;

  // ---- Feature 10: missed-day banner (yesterday had an entry but no activity) ----
  const yesterdayDt = new Date(TODAY); yesterdayDt.setDate(yesterdayDt.getDate() - 1);
  const yKey = fmtDate(yesterdayDt);
  const yEntry = data.calendar.find(c => c.date === yKey);
  const yState = state.days[yKey];
  const ySkippable = yEntry && ['DSA','LLD','MOCK','APPLY','POWER'].includes(yEntry.type);
  const yMissed = ySkippable && !isActive(yState) && !state[`dismissedMiss_${yKey}`];
  const dismissMiss = () => update(prev => ({ ...prev, [`dismissedMiss_${yKey}`]: true }));
  function shiftRemaining() {
    if (!confirm('Shift every remaining day forward by 1? This rewrites the whole calendar from today onward.')) return;
    dismissMiss();
    shiftScheduleForward(update, 1);
  }

  // ---- Feature 9: markdown weekly digest ----
  function digest() {
    const lines = [];
    lines.push(`# Weekly digest — ${weekDays[0]} → ${weekDays[6]}`);
    lines.push('');
    lines.push(`- Streak: **${streak} days**`);
    lines.push(`- Planned: **${plannedHrs}h** · Actual: **${actualHrs.toFixed(1)}h** (${hoursPctMatch}%)`);
    lines.push(`- Tasks closed this week: **${weekDays.filter(k => state.days[k]?.done).length}/7**`);
    const energyScores = weekDays.map(k => state.days[k]?.energy).filter(Boolean);
    if (energyScores.length) lines.push(`- Avg energy: **${(energyScores.reduce((a,b)=>a+b,0)/energyScores.length).toFixed(1)}/5**`);
    lines.push('');
    lines.push('## Days');
    for (const k of weekDays) {
      const e = data.calendar.find(c => c.date === k);
      const s = state.days[k] || {};
      const done = s.done ? 'x' : ' ';
      lines.push(`- [${done}] **${k}** (${e?.type || 'OFF'}): ${s.actualHours || 0}h${s.energy ? ` · energy ${s.energy}/5` : ''}${s.note ? `\n    > ${s.note.replace(/\n/g, ' ')}` : ''}`);
    }
    const dueWeak = Object.values(state.weak || {}).filter(w => w && w.dueDate <= today);
    if (dueWeak.length) {
      lines.push('');
      lines.push('## Weak problems due');
      for (const w of dueWeak) lines.push(`- ${w.topic} — ${w.title} (step ${(w.intervalIdx||0)+1}/${SRS_INTERVALS.length})`);
    }
    const upMocks = data.mocks.map(m => ({ m, s: state.mocks[m.id] })).filter(x => x.s?.score);
    if (upMocks.length) {
      lines.push('');
      lines.push('## Mocks logged (all-time)');
      for (const { m, s } of upMocks) lines.push(`- ${m.id} (${m.date}, ${m.type}): **${s.score}/10**${s.improve ? ` — to improve: ${s.improve}` : ''}`);
    }
    return lines.join('\n');
  }
  function copyDigest() {
    const text = digest();
    navigator.clipboard?.writeText(text).then(
      () => alert('Weekly digest copied to clipboard.'),
      () => prompt('Copy this digest:', text)
    );
  }
  function downloadDigest() {
    const blob = new Blob([digest()], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = `digest-${weekDays[0]}.md`;
    a.click();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }

  // ---- Backup: export / import full state blob ----
  const fileInputRef = React.useRef(null);
  function handleImport(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    if (!confirm(`Import "${file.name}"? This will OVERWRITE your current data. (Tip: export first if unsure.)`)) {
      e.target.value = '';
      return;
    }
    importBackup(file).then(() => {
      alert('Backup imported. Reloading…');
      window.location.reload();
    }).catch(err => {
      alert(`Import failed: ${err.message}`);
      e.target.value = '';
    });
  }

  // ---- Feature 1 integration: weak problems due today ----
  const dueWeak = Object.values(state.weak || {}).filter(w => w && w.dueDate <= today);

  return (
    <div className="fade-in">
      <div className="section-h">
        <div>
          <div className="kicker">{TODAY.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })} · IST</div>
          <h1 className="h-title">
            {rawElapsed < 1
              ? <>Sprint starts in <em>{1 - rawElapsed}</em> day{1 - rawElapsed === 1 ? '' : 's'}.</>
              : rawElapsed > sprintTotal
                ? <>Sprint <em>complete</em>.</>
                : <>Day <em>{sprintElapsed}</em> of {sprintTotal}.</>}<br/>
            {daysToLaunch > 0 ? <>Interviews in <em>{daysToLaunch}</em> days.</> : <em>Interviews live.</em>}
          </h1>
        </div>
        <div style={{display:'flex',alignItems:'center',gap:'14px'}}>
          <StreakRing count={streak} goal={7} />
          <div>
            <div className="mono" style={{fontSize:'10px',color:'var(--ink-3)',letterSpacing:'0.1em'}}>STREAK</div>
            <div className="mono" style={{fontSize:'11px',color:'var(--ink-2)'}}>active day = done · note · or hours</div>
          </div>
        </div>
      </div>

      {/* Missed-day banner */}
      {yMissed && (
        <div className="card" style={{marginBottom:'18px', borderColor:'var(--warn)', background:'oklch(0.22 0.05 65 / 0.25)'}}>
          <div style={{display:'flex', alignItems:'center', gap:'14px', flexWrap:'wrap'}}>
            <div style={{flex:1, minWidth:'260px'}}>
              <div className="kicker" style={{color:'var(--warn)'}}>Missed: {yKey} ({yEntry.type})</div>
              <div style={{fontFamily:'var(--serif)',fontSize:'20px',marginTop:'2px'}}>
                Yesterday slipped. Shift the remaining schedule, or absorb it.
              </div>
            </div>
            <button className="btn primary" onClick={shiftRemaining}>Shift everything +1 day</button>
            <button className="btn" onClick={() => { setDay({}); update(prev => ({...prev, days: { ...prev.days, [yKey]: { ...prev.days[yKey], absorbed: true, note: (prev.days[yKey]?.note || '') + ' [absorbed]' } }})); dismissMiss(); }}>Absorb</button>
            <button className="btn ghost" onClick={dismissMiss}>Dismiss</button>
          </div>
        </div>
      )}

      {/* Stats grid */}
      <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:'14px', marginBottom:'24px'}}>
        <Stat label="Sprint" value={<><CountUp to={Math.round(sprintPct)} />%</>} sub={`${sprintElapsed} / ${sprintTotal} days`} />
        <Stat label="Current Phase" value={phase.name.replace('PHASE ', 'P')} sub={phase.dates} accent />
        <Stat label="Tasks Closed" value={<CountUp to={totalDone} />} sub={`of ${data.calendar.length}`} />
        <Stat label="Days to Launch" value={<CountUp to={Math.max(0, daysToLaunch)} />} sub={data.meta.interviewLaunch} />
      </div>

      {/* Phase progress strip */}
      <div className="card" style={{marginBottom:'18px'}}>
        <div className="card-h">
          <div>
            <div className="kicker">Phase Progress</div>
            <div style={{fontFamily:'var(--serif)',fontSize:'24px',marginTop:'4px',letterSpacing:'-0.01em'}}>{phase.focus}</div>
          </div>
          <div style={{textAlign:'right'}}>
            <div className="mono" style={{fontSize:'11px',color:'var(--ink-2)'}}>{phaseElapsed} / {phaseTotal} days</div>
            <div className="mono" style={{fontSize:'24px',marginTop:'2px'}}>{Math.round(phasePct)}%</div>
          </div>
        </div>
        <Bar value={phaseElapsed} total={phaseTotal} />
        <div style={{display:'flex',justifyContent:'space-between',marginTop:'10px'}}>
          <span className="mono muted" style={{fontSize:'10px'}}>→ {phase.output}</span>
          <span className="mono muted" style={{fontSize:'10px'}}>{phase.goal}</span>
        </div>
      </div>

      {/* Hours this week + digest export + backup */}
      <div className="card" style={{marginBottom:'18px'}}>
        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 220px', gap:'24px', alignItems:'center'}}>
          <div>
            <div className="kicker">Hours this week</div>
            <div style={{fontFamily:'var(--serif)',fontSize:'28px',marginTop:'4px'}}>
              <span style={{color: hoursPctMatch >= 80 ? 'var(--accent)' : hoursPctMatch >= 50 ? 'var(--warn)' : 'var(--rose)'}}>{actualHrs.toFixed(1)}h</span>
              <span className="muted" style={{fontSize:'18px'}}> / {plannedHrs}h planned · {hoursPctMatch}%</span>
            </div>
          </div>
          <Sparkline values={weekDays.map(k => parseFloat(state.days[k]?.actualHours) || 0)} width={200} height={42} />
          <div style={{display:'flex',gap:'8px',justifyContent:'flex-end',flexWrap:'wrap'}}>
            <button className="btn" onClick={copyDigest}>Copy digest</button>
            <button className="btn primary" onClick={downloadDigest}>Download .md</button>
          </div>
        </div>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:'12px',marginTop:'14px',paddingTop:'12px',borderTop:'1px solid var(--line-soft)'}}>
          <div className="mono muted" style={{fontSize:'10px',letterSpacing:'0.1em'}}>
            BACKUP · all data stays in this browser. Export regularly.
          </div>
          <div style={{display:'flex',gap:'8px'}}>
            <input ref={fileInputRef} type="file" accept="application/json,.json" onChange={handleImport} style={{display:'none'}}/>
            <button className="btn" onClick={() => fileInputRef.current?.click()}>Import backup…</button>
            <button className="btn" onClick={exportBackup}>Export backup</button>
          </div>
        </div>
      </div>

      {/* Today's task card */}
      {todayEntry ? (
        <div className="card" style={{marginBottom:'24px', borderColor: 'var(--accent)', boxShadow:'0 0 0 1px var(--accent), 0 8px 32px oklch(0.86 0.18 130 / 0.08)'}}>
          <div className="card-h">
            <div style={{display:'flex',alignItems:'center',gap:'12px',flexWrap:'wrap'}}>
              <div className="kicker">Today's Mission</div>
              <PhasePill phase={todayEntry.phase} />
              <TypePill type={todayEntry.type} />
              <Pill>{todayEntry.hours}h planned</Pill>
            </div>
            <Check on={dayState.done} onClick={() => setDay({ done: !dayState.done })} size={22} />
          </div>

          <div style={{display:'grid', gridTemplateColumns: todayEntry.dsa && todayEntry.lld ? '1fr 1fr' : '1fr', gap:'18px', marginTop:'10px'}}>
            {todayEntry.dsa && (
              <div>
                <div className="mono" style={{fontSize:'10px',letterSpacing:'0.14em',color:'oklch(0.86 0.13 200)',marginBottom:'8px'}}>DSA</div>
                <p style={{lineHeight:'1.6', color:'var(--ink)'}}>{todayEntry.dsa}</p>
              </div>
            )}
            {todayEntry.lld && (
              <div>
                <div className="mono" style={{fontSize:'10px',letterSpacing:'0.14em',color:'oklch(0.84 0.14 165)',marginBottom:'8px'}}>LLD / OTHER</div>
                <p style={{lineHeight:'1.6', color:'var(--ink)'}}>{todayEntry.lld}</p>
              </div>
            )}
          </div>

          {/* Hours + energy + sleep inputs */}
          <div style={{display:'grid', gridTemplateColumns:'140px 1fr 1fr', gap:'18px', marginTop:'18px', paddingTop:'14px', borderTop:'1px solid var(--line-soft)', alignItems:'center'}}>
            <div>
              <div className="mono" style={{fontSize:'10px',letterSpacing:'0.12em',color:'var(--ink-3)',marginBottom:'4px'}}>ACTUAL HOURS</div>
              <input className="input" type="number" step="0.25" min="0" placeholder="0.0"
                value={dayState.actualHours || ''}
                onChange={e => setDay({ actualHours: e.target.value })}
                style={{padding:'8px 10px',fontFamily:'var(--mono)'}}/>
            </div>
            <div>
              <div className="mono" style={{fontSize:'10px',letterSpacing:'0.12em',color:'var(--ink-3)',marginBottom:'6px'}}>ENERGY (1–5)</div>
              <Rating value={dayState.energy || 0} onChange={v => setDay({ energy: v })} color="var(--accent)"/>
            </div>
            <div>
              <div className="mono" style={{fontSize:'10px',letterSpacing:'0.12em',color:'var(--ink-3)',marginBottom:'6px'}}>SLEEP QUALITY (1–5)</div>
              <Rating value={dayState.sleep || 0} onChange={v => setDay({ sleep: v })} color="oklch(0.82 0.12 240)"/>
            </div>
          </div>

          <div style={{marginTop:'14px'}}>
            <textarea
              className="textarea"
              placeholder="Day notes — wins, blockers, weak problems..."
              value={dayState.note || ''}
              onChange={e => setDay({ note: e.target.value })}
            />
          </div>
        </div>
      ) : (
        <div className="card" style={{textAlign:'center', padding:'48px', marginBottom:'24px'}}>
          <div className="kicker">Off-schedule day</div>
          <div style={{fontFamily:'var(--serif)',fontSize:'28px',marginTop:'8px'}}>Rest. Live. Reset.</div>
        </div>
      )}

      {/* Weak problems due */}
      {dueWeak.length > 0 && (
        <div className="card" style={{marginBottom:'24px', borderColor:'var(--rose)'}}>
          <div className="card-h">
            <div className="kicker" style={{color:'var(--rose)'}}>Weak problems due ({dueWeak.length})</div>
            <button className="btn ghost" onClick={() => update({ view: 'revisit' })}>Open queue →</button>
          </div>
          <div className="col" style={{gap:'4px'}}>
            {dueWeak.slice(0, 4).map(w => (
              <div key={w.id} style={{display:'flex',gap:'10px',fontSize:'12px',color:'var(--ink-2)'}}>
                <span className="mono muted" style={{minWidth:'160px'}}>{w.topic}</span>
                <span>{w.title}</span>
              </div>
            ))}
            {dueWeak.length > 4 && <div className="mono muted" style={{fontSize:'10px',marginTop:'4px'}}>+ {dueWeak.length - 4} more</div>}
          </div>
        </div>
      )}

      {/* Upcoming */}
      <div className="card flat" style={{padding: 0}}>
        <div className="card-h">
          <div>
            <div className="kicker">Up Next</div>
            <div className="card-title">The road ahead</div>
          </div>
        </div>

        <div style={{display:'flex', flexDirection:'column', gap:'1px', borderRadius:'var(--r-3)', overflow:'hidden', border:'1px solid var(--line-soft)'}}>
          {upcoming.map((d, i) => {
            const ds = state.days[d.date] || {};
            const isToday = d.date === today;
            return (
              <div key={d.date}
                onClick={() => update({ view: 'calendar', focusDate: d.date })}
                style={{
                  background: isToday ? 'var(--bg-3)' : 'var(--bg-2)',
                  padding: '14px 18px',
                  display: 'grid',
                  gridTemplateColumns: '60px 60px 90px 1fr 80px 24px',
                  gap: '16px',
                  alignItems: 'center',
                  cursor: 'pointer',
                  transition: 'background 0.15s',
                  animation: `fadeUp 0.4s ${i * 50}ms cubic-bezier(0.2, 0.8, 0.2, 1) both`,
                }}
                onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                onMouseLeave={e => e.currentTarget.style.background = isToday ? 'var(--bg-3)' : 'var(--bg-2)'}
              >
                <div className="mono" style={{fontSize:'11px', color: isToday ? 'var(--accent)' : 'var(--ink-3)', fontWeight: 600}}>
                  {isToday ? 'TODAY' : d.day.toUpperCase()}
                </div>
                <div className="mono" style={{fontSize:'11px',color:'var(--ink-2)'}}>
                  {d.display.split('(')[1].replace(')','')}
                </div>
                <TypePill type={d.type} />
                <div style={{fontSize:'13px', color:'var(--ink-2)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>
                  {(d.dsa || d.lld).split('.')[0].slice(0, 80)}
                </div>
                <div className="mono muted" style={{fontSize:'11px', textAlign:'right'}}>{d.hours}h</div>
                <Check on={ds.done} onClick={(e) => { e.stopPropagation(); update(prev => ({ ...prev, days: { ...prev.days, [d.date]: { ...prev.days[d.date], done: !ds.done } } })); }} size={16} />
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

window.TodayView = TodayView;
