// Budget dashboard + Milestones summary views
function BudgetView({ tasks, updateTask, t, lang, perms, workstreams }) {
  const { money, moneyShort } = AOX_UTIL;
  const [editingId, setEditingId] = useState(null);
  const canEdit = perms?.canEdit !== false;

  const byPhase = useMemo(() => {
    const g = {};
    tasks.forEach(tk => {
      const k = tk.phase;
      if (!g[k]) g[k] = { phase: k, plan: 0, actual: 0, count: 0 };
      g[k].plan += tk.budgetPlan || 0;
      g[k].actual += tk.budgetActual || 0;
      g[k].count += 1;
    });
    return Object.values(g).sort((a,b)=>a.phase.localeCompare(b.phase));
  }, [tasks]);

  const byTrack = useMemo(() => {
    const g = {};
    tasks.forEach(tk => {
      const k = tk.workstream;
      if (!g[k]) g[k] = { track: k, plan: 0, actual: 0 };
      g[k].plan += tk.budgetPlan || 0;
      g[k].actual += tk.budgetActual || 0;
    });
    return Object.values(g).sort((a,b)=>b.plan-a.plan);
  }, [tasks]);

  const totalPlan = tasks.reduce((a,b)=>a + (b.budgetPlan||0), 0);
  const totalActual = tasks.reduce((a,b)=>a + (b.budgetActual||0), 0);
  const remaining = totalPlan - totalActual;

  const top = [...tasks].filter(t=>t.budgetPlan).sort((a,b)=>b.budgetPlan-a.budgetPlan).slice(0,10);
  const maxPlan = Math.max(1, ...byPhase.map(p=>p.plan));

  return (
    <div style={{display:'flex', flexDirection:'column', gap: 18}}>
      {/* KPI cards */}
      <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 12}}>
        {[
          { label: t.labels.totalBudget, value: money(totalPlan), sub: `${tasks.length} ${t.labels.tasksCount}` },
          { label: t.labels.spent, value: money(totalActual), sub: `${totalPlan ? Math.round(totalActual/totalPlan*100) : 0}%` },
          { label: t.labels.remaining, value: money(remaining), sub: '' },
          { label: lang==='en'?'At-risk items':'고위험 항목', value: tasks.filter(t=>t.risk==='High').length, sub: lang==='en'?'High risk':'High risk' },
        ].map((k, i) => (
          <div key={i} style={{
            background:'var(--bg-solid)', border:'1px solid var(--border)',
            borderRadius: 12, padding: '14px 16px', boxShadow:'var(--shadow-1)'
          }}>
            <div style={{fontSize: 11, color:'var(--fg-muted)', fontWeight:600, textTransform:'uppercase', letterSpacing: 0.06}}>{k.label}</div>
            <div style={{fontSize: 22, fontWeight: 600, marginTop: 6, letterSpacing:-0.015, fontVariantNumeric:'tabular-nums'}}>{k.value}</div>
            {k.sub && <div style={{fontSize: 11.5, color:'var(--fg-muted)', marginTop: 2}}>{k.sub}</div>}
          </div>
        ))}
      </div>

      {/* Phase breakdown */}
      <div style={{
        background:'var(--bg-solid)', border:'1px solid var(--border)',
        borderRadius: 12, padding: 16, boxShadow:'var(--shadow-1)'
      }}>
        <div style={{fontSize: 14, fontWeight: 600, marginBottom: 12}}>
          {lang==='en' ? 'Budget by Phase' : '단계별 예산'}
        </div>
        <div style={{display:'flex', flexDirection:'column', gap: 10}}>
          {byPhase.map(p => {
            const phaseN = (p.phase||'').match(/\d/)?.[0] || '3';
            const pctActual = p.plan ? (p.actual / p.plan) * 100 : 0;
            const w = (p.plan / maxPlan) * 100;
            return (
              <div key={p.phase}>
                <div style={{display:'flex', alignItems:'center', gap:10, marginBottom: 4}}>
                  <PhaseTag phase={p.phase}/>
                  <span style={{fontSize: 13, fontWeight: 500}}>{p.phase}</span>
                  <span className="muted" style={{fontSize: 11}}>{p.count} {t.labels.tasksCount}</span>
                  <span style={{flex:1}}/>
                  <span className="mono" style={{fontSize: 12.5, fontWeight:500}}>{money(p.plan)}</span>
                </div>
                <div style={{height: 12, background:'var(--surface-2)', borderRadius: 6, overflow:'hidden', position:'relative'}}>
                  <div style={{
                    width: w+'%', height:'100%',
                    background: `var(--phase${phaseN})`, opacity: 0.35
                  }}/>
                  <div style={{
                    position:'absolute', left:0, top:0,
                    width: Math.min(w, (p.actual/maxPlan)*100)+'%', height:'100%',
                    background: `var(--phase${phaseN})`
                  }}/>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Track breakdown */}
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap: 12}}>
        <div style={{
          background:'var(--bg-solid)', border:'1px solid var(--border)',
          borderRadius: 12, padding: 16, boxShadow:'var(--shadow-1)'
        }}>
          <div style={{fontSize: 14, fontWeight: 600, marginBottom: 12}}>
            {lang==='en' ? 'By Track' : '트랙별'}
          </div>
          {byTrack.map(tr => {
            const ws = workstreams?.find(w => w.key === tr.track);
            const color = ws ? ws.color : (tr.track === '개발' ? 'var(--track-dev)' : tr.track === 'PR·마케팅' ? 'var(--track-prm)' : 'var(--track-ops)');
            const pct = totalPlan ? (tr.plan / totalPlan) * 100 : 0;
            return (
              <div key={tr.track} style={{marginBottom: 10}}>
                <div style={{display:'flex', alignItems:'center', gap:8, marginBottom: 4}}>
                  <span style={{width:8, height:8, borderRadius:'50%', background: color}}/>
                  <span style={{fontSize: 13, fontWeight: 500}}>{tr.track}</span>
                  <span style={{flex:1}}/>
                  <span className="mono muted" style={{fontSize: 11}}>{pct.toFixed(0)}%</span>
                  <span className="mono" style={{fontSize: 12, minWidth: 80, textAlign:'right'}}>{moneyShort(tr.plan)}</span>
                </div>
                <div style={{height: 6, background:'var(--surface-2)', borderRadius: 3, overflow:'hidden'}}>
                  <div style={{width: pct+'%', height:'100%', background: color}}/>
                </div>
              </div>
            );
          })}
        </div>

        <div style={{
          background:'var(--bg-solid)', border:'1px solid var(--border)',
          borderRadius: 12, padding: 16, boxShadow:'var(--shadow-1)'
        }}>
          <div style={{fontSize: 14, fontWeight: 600, marginBottom: 12}}>
            {lang==='en' ? 'Top 10 line items' : '상위 10개 항목'}
          </div>
          <div style={{display:'flex', flexDirection:'column', gap: 6}}>
            {top.map(tk => (
              <div key={tk.id} style={{
                display:'grid', gridTemplateColumns: '1fr auto auto',
                gap: 8, alignItems:'center',
                padding: '6px 8px',
                borderRadius: 6,
                background: 'var(--surface-2)'
              }}>
                <div style={{fontSize: 12.5, overflow:'hidden', whiteSpace:'nowrap', textOverflow:'ellipsis'}}>
                  <span className="muted mono" style={{fontSize:10.5, marginRight:6}}>{tk.id}</span>
                  {tk.task}
                </div>
                {editingId === tk.id ? (
                  <input type="number" defaultValue={tk.budgetPlan} autoFocus
                    onBlur={e=>{ updateTask(tk.id, {budgetPlan: Number(e.target.value)||0}); setEditingId(null); }}
                    onKeyDown={e=>{ if(e.key==='Enter') e.target.blur(); if(e.key==='Escape') setEditingId(null); }}
                    style={{width: 110, padding:'3px 6px', border:'2px solid var(--accent)', borderRadius: 5, fontFamily:'var(--font-mono)', fontSize: 11.5}}
                  />
                ) : (
                  <span onDoubleClick={()=>{ if (canEdit) setEditingId(tk.id); }} className="mono"
                    style={{fontSize: 12, cursor: canEdit ? 'cell' : 'default', minWidth: 110, textAlign:'right',
                      color: canEdit ? undefined : 'var(--fg-muted)'}}>{money(tk.budgetPlan)}</span>
                )}
                <RiskPill risk={tk.risk} t={t}/>
              </div>
            ))}
          </div>
          <div className="muted" style={{fontSize: 11, marginTop: 10}}>
            {lang==='en' ? 'Double-click amount to edit.' : '금액을 더블클릭하면 바로 수정됩니다.'}
          </div>
        </div>
      </div>
    </div>
  );
}

function MilestonesView({ tasks, t, lang, milestones: msProp, phaseConfig: phProp }) {
  const { parseDate, diffDays, fmtDate } = AOX_UTIL;
  // New DB shape: { id, name, target_date, icon, color (hex), sort_order, description }
  // Legacy window.AOX_MILESTONES shape: { id, label, labelEn, date, color (name) }
  const rawMs = msProp || window.AOX_MILESTONES || [];
  const milestones = rawMs.map((m, i) => {
    // Normalize both shapes into a single display shape
    const isNew = 'target_date' in m || 'name' in m;
    const date = isNew ? m.target_date : m.date;
    const label = isNew ? m.name : m.label;
    const labelEn = isNew ? m.name : m.labelEn;
    // Resolve color — hex string passes through, legacy names map to phase colors
    let color = m.color;
    if (!color || /^(amber|violet|emerald|green|blue)$/i.test(color)) {
      color = color === 'amber' ? 'var(--phase1)'
           : color === 'violet' ? 'var(--phase2)'
           : 'var(--phase3)';
    }
    return { ...m, _date: date, _label: label, _labelEn: labelEn, _color: color, _icon: m.icon || '◆', _idx: i };
  });
  // Use the LAST milestone (furthest-right in sort order, typically launch) as the hero
  const hero = milestones.length ? milestones[milestones.length - 1] : null;
  const today = new Date();

  const phases = (phProp && phProp.length ? phProp : [
    { phase_code:'Phase 1' }, { phase_code:'Phase 2' }, { phase_code:'Phase 3' }, { phase_code:'Phase 4' }
  ]);

  return (
    <div style={{display:'flex', flexDirection:'column', gap: 18, maxWidth: 920, margin:'0 auto', width:'100%'}}>
      {/* Hero countdown */}
      {hero && (() => {
        const dd = diffDays(today, parseDate(hero._date));
        return (
          <div style={{
            background:'linear-gradient(135deg, var(--phase3) 0%, var(--phase2) 100%)',
            color:'#fff',
            borderRadius: 16,
            padding: '24px 28px',
            boxShadow: 'var(--shadow-2)',
            display:'grid', gridTemplateColumns:'1fr auto', alignItems:'center', gap: 20
          }}>
            <div>
              <div style={{fontSize: 12, opacity: 0.8, fontWeight: 500, textTransform:'uppercase', letterSpacing: 0.08}}>
                {t.labels.daysToLaunch}
              </div>
              <div style={{fontSize: 18, fontWeight: 600, marginTop: 4}}>
                {hero._icon} {lang==='en'?hero._labelEn:hero._label} · {hero._date}
              </div>
            </div>
            <div style={{fontSize: 56, fontWeight: 700, letterSpacing: -0.03, fontVariantNumeric:'tabular-nums'}}>
              {dd === 0 ? 'D-DAY' : (
                <>
                  {dd > 0 ? 'D-' : 'D+'}
                  <RollingNumber target={Math.abs(dd)} duration={800}/>
                </>
              )}
            </div>
          </div>
        );
      })()}

      {/* Milestone cards */}
      <div style={{display:'grid', gridTemplateColumns: `repeat(${Math.min(Math.max(milestones.length,1),3)}, 1fr)`, gap: 12}}>
        {milestones.map(m => {
          const dd = diffDays(today, parseDate(m._date));
          const color = m._color;
          const relevant = tasks.filter(tk => tk.milestoneId === m.id).length;
          const done = tasks.filter(tk => tk.milestoneId === m.id && tk.status === 'Done').length;
          return (
            <div key={m.id} style={{
              background:'var(--bg-solid)', border:'1px solid var(--border)',
              borderRadius: 12, padding: 16, boxShadow: 'var(--shadow-1)',
              borderLeft: `3px solid ${color}`
            }}>
              <div style={{display:'flex', alignItems:'center', gap: 8, marginBottom: 8}}>
                <span style={{color, fontSize: 16}}>{m._icon}</span>
                <span style={{fontSize: 15, fontWeight: 600}}>{lang==='en'?m._labelEn:m._label}</span>
              </div>
              <div className="mono muted" style={{fontSize: 12}}>{m._date}</div>
              <div style={{fontSize: 26, fontWeight: 700, letterSpacing: -0.02, marginTop: 8, color}}>
                {dd === 0 ? (lang==='en'?'Today':'오늘') : dd > 0 ? (
                  <>D-<RollingNumber target={dd} duration={800}/></>
                ) : (
                  <>+<RollingNumber target={-dd} duration={800}/>{lang==='en'?'d':'일'}</>
                )}
              </div>
              <div style={{marginTop: 12, display:'flex', justifyContent:'space-between', fontSize: 11.5}}>
                <span className="muted">{lang==='en'?'Milestone tasks':'마일스톤 태스크'}</span>
                <span className="mono">{done}/{relevant}</span>
              </div>
            </div>
          );
        })}
      </div>

      {/* Timeline list */}
      <div style={{
        background:'var(--bg-solid)', border:'1px solid var(--border)',
        borderRadius: 12, padding: 20, boxShadow:'var(--shadow-1)'
      }}>
        <div style={{fontSize: 14, fontWeight: 600, marginBottom: 14}}>
          {lang==='en' ? 'Phase timeline' : '단계별 타임라인'}
        </div>
        <div style={{display:'flex', flexDirection:'column', gap: 12}}>
          {phases.map((phRow, idx) => {
            const ph = phRow.phase_code;
            const items = tasks.filter(tk => tk.phase === ph);
            if (!items.length) return null;
            const phaseN = idx + 1;
            const start = items.reduce((a,b)=>a<b.start?a:b.start, items[0].start);
            const end = items.reduce((a,b)=>a>b.end?a:b.end, items[0].end);
            const done = items.filter(x => x.status==='Done').length;
            const pct = Math.round(items.reduce((a,b)=>a+(b.progress||0),0) / items.length);
            return (
              <div key={ph} style={{
                display:'grid', gridTemplateColumns: '140px 1fr auto', gap: 16, alignItems:'center',
                padding: '10px 12px', borderRadius: 10,
                background: 'var(--surface-2)'
              }}>
                <div>
                  <PhaseTag phase={ph}/>
                  <div style={{fontSize: 13.5, fontWeight: 600, marginTop: 2}}>{ph}</div>
                  {phRow.label && <div style={{fontSize: 11, color:'var(--fg-muted)'}}>{phRow.label}</div>}
                </div>
                <div>
                  <div className="mono muted" style={{fontSize: 11, marginBottom: 6}}>{start} → {end}</div>
                  <div style={{height: 6, background:'var(--bg-solid)', borderRadius: 3, overflow:'hidden'}}>
                    <div style={{width: pct+'%', height:'100%', background: `var(--phase${phaseN})`}}/>
                  </div>
                </div>
                <div style={{textAlign:'right'}}>
                  <div style={{fontSize: 18, fontWeight: 600, fontVariantNumeric:'tabular-nums'}}>{pct}%</div>
                  <div className="muted" style={{fontSize: 11}}>{done}/{items.length}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

window.BudgetView = BudgetView;
window.MilestonesView = MilestonesView;
