/* === Page screens === */

const NAV = [
  { id: 'dashboard', glyph: '◐', label: 'Dashboard' },
  { id: 'expenses',  glyph: '≡', label: 'Expenses' },
  { id: 'fixed',     glyph: '◇', label: 'Fixed costs' },
  { id: 'goals',     glyph: '✦', label: 'Savings' },
  { id: 'income',    glyph: '↑', label: 'Income' },
  { id: 'tags',      glyph: '◯', label: 'Tags' },
  { id: 'meals',     glyph: '◫', label: 'Meals' },
  { id: 'tasks',     glyph: '☐', label: 'Tasks' },
  { id: 'family',    glyph: '◈', label: 'Family' },
  { id: 'settings',  glyph: '⌘', label: 'Settings' },
];

// ──────────────────────────────────────────────────
// DASHBOARD
// ──────────────────────────────────────────────────
function DashboardScreen({ state, setState, setOpenModal, setRoute }) {
  const { income, fixed, expenses, extra, tags, goals, history, activeMonth, _allExpenses, pool, closedMonths, tasks = [], family = [] } = state;
  const fixedTotal = fixed.reduce((s, f) => s + monthlyEquiv(f), 0);
  const expensesTotal = expenses.reduce((s, e) => s + e.amount, 0);
  const extraTotal = (extra || []).reduce((s, x) => s + x.amount, 0);
  const remaining = income + extraTotal - fixedTotal - expensesTotal;

  // Per-tag spend (active month) for over-budget alert
  const tagSpend = {};
  expenses.forEach(e => { tagSpend[e.tagId] = (tagSpend[e.tagId] || 0) + e.amount; });
  const overTags = tags.filter(t => (t.budget || 0) > 0 && (tagSpend[t.id] || 0) > t.budget)
    .map(t => ({ tag: t, spent: tagSpend[t.id] || 0, over: (tagSpend[t.id] || 0) - t.budget }))
    .sort((a, b) => b.over - a.over);
  const nearTags = tags.filter(t => (t.budget || 0) > 0
    && (tagSpend[t.id] || 0) <= t.budget
    && (tagSpend[t.id] || 0) / t.budget >= 0.85);
  const negative = remaining < 0;
  const isLive = isCurrentMonth(activeMonth);

  // Spending by tag
  const byTag = {};
  expenses.forEach(e => {
    byTag[e.tagId] = (byTag[e.tagId] || 0) + e.amount;
  });
  const tagData = Object.entries(byTag)
    .map(([tagId, value]) => {
      const t = tagById(tags, tagId);
      return { tagId, value, color: TAG_COLORS[t.color], name: t.name };
    })
    .sort((a, b) => b.value - a.value);

  // Days into the month / pace — only meaningful for current month
  const daysInMonth = daysInMonthKey(activeMonth);
  const dayOfMonth = isLive ? TODAY.getDate() : daysInMonth;
  const daysLeft = Math.max(0, daysInMonth - dayOfMonth);
  const dailyAvg = expensesTotal / Math.max(1, dayOfMonth);
  const projected = fixedTotal + dailyAvg * daysInMonth;

  // Latest 6 expenses (within selected month)
  const recent = [...expenses].sort((a, b) => b.date.localeCompare(a.date)).slice(0, 6);

  // History sparkline — synthesize from all expenses for last 6 months
  const sparkData = React.useMemo(() => {
    const out = [];
    const all = _allExpenses || expenses;
    for (let i = 5; i >= 0; i--) {
      const k = shiftMonth(activeMonth, -i);
      const sum = all.filter(e => monthKey(e.date) === k).reduce((s, e) => s + e.amount, 0);
      out.push(sum);
    }
    return out;
  }, [_allExpenses, activeMonth]);
  const sparkAvg = sparkData.reduce((s, v) => s + v, 0) / sparkData.length;

  return (
    <>
      {/* Hero */}
      <div className="hero">
        <div>
          <div className="hero-eyebrow">
            {isLive ? <>Remaining this month<span className="hide-mobile"> · {formatMonthKey(activeMonth)}</span></> : <>Net for {formatMonthKey(activeMonth)}</>}
          </div>
          <div className={`hero-amount ${negative ? 'negative' : ''}`}>
            <span className="sign">{negative ? '−' : ''}$</span>
            {Math.abs(remaining).toLocaleString('en-US', { maximumFractionDigits: 0 })}
            <span className="cents">.{Math.abs(remaining).toFixed(2).split('.')[1]}</span>
          </div>
          <div className="hero-meta">
            {isLive ? (
              <>
                <div className="hero-meta-item">
                  <div className="label">Daily allowance</div>
                  <div className="value">{fmt(daysLeft > 0 ? remaining / daysLeft : 0, { cents: false })}</div>
                </div>
                <div className="hero-meta-item">
                  <div className="label">Days remaining</div>
                  <div className="value">{daysLeft}</div>
                </div>
                <div className="hero-meta-item">
                  <div className="label">Pace</div>
                  <div className="value">
                    {projected <= income
                      ? <span style={{ color: 'var(--pos)' }}>On track</span>
                      : <span style={{ color: 'var(--ochre)' }}>Slightly over</span>}
                  </div>
                </div>
              </>
            ) : (
              <>
                <div className="hero-meta-item">
                  <div className="label">Avg / day</div>
                  <div className="value">{fmt(expensesTotal / daysInMonth, { cents: false })}</div>
                </div>
                <div className="hero-meta-item">
                  <div className="label">Transactions</div>
                  <div className="value">{expenses.length}</div>
                </div>
                <div className="hero-meta-item">
                  <div className="label">Status</div>
                  <div className="value"><span className="muted">Closed month</span></div>
                </div>
              </>
            )}
          </div>
        </div>

        {/* Cashflow breakdown */}
        <div className="flow">
          <div className="flow-row income">
            <div className="label"><span className="glyph">+</span>Income</div>
            <div className="amt">{fmt(income)}</div>
          </div>
          {extraTotal > 0 && (
            <div className="flow-row income">
              <div className="label"><span className="glyph">+</span>Extra income · {extra.length}</div>
              <div className="amt" style={{ color: 'var(--pos)' }}>{fmt(extraTotal)}</div>
            </div>
          )}
          <div className="flow-row expense">
            <div className="label"><span className="glyph">◇</span>Fixed costs · {fixed.length}</div>
            <div className="amt">{fmt(fixedTotal)}</div>
          </div>
          <div className="flow-row expense">
            <div className="label"><span className="glyph">≡</span>Variable spending · {expenses.length}</div>
            <div className="amt">{fmt(expensesTotal)}</div>
          </div>
          <div className="flow-row total">
            <div className="label">Remaining</div>
            <div className="amt num" style={{ color: negative ? 'var(--neg)' : 'var(--ink)' }}>
              {negative ? '−' : ''}${Math.abs(remaining).toFixed(2)}
            </div>
          </div>
        </div>

        {/* Over-budget alert strip */}
        {(overTags.length > 0 || nearTags.length > 0) && (
          <div className="budget-alert-strip">
            {overTags.length > 0 && (
              <div className="alert-row over">
                <span className="alert-icon">!</span>
                <span className="alert-label">
                  {overTags.length === 1
                    ? `${overTags[0].tag.name} over budget`
                    : `${overTags.length} tags over budget`}
                </span>
                <div className="alert-tags">
                  {overTags.slice(0, 4).map(({ tag, over }) => (
                    <span key={tag.id} className="alert-tag-chip">
                      <Tag tag={tag} />
                      <span className="num neg">+{fmt(over, { cents: false })}</span>
                    </span>
                  ))}
                </div>
              </div>
            )}
            {nearTags.length > 0 && overTags.length === 0 && (
              <div className="alert-row warn">
                <span className="alert-icon">~</span>
                <span className="alert-label">
                  {nearTags.length === 1
                    ? `${nearTags[0].name} near limit`
                    : `${nearTags.length} tags near limit`}
                </span>
                <div className="alert-tags">
                  {nearTags.slice(0, 4).map(t => (
                    <span key={t.id} className="alert-tag-chip">
                      <Tag tag={t} />
                      <span className="num muted">{Math.round((tagSpend[t.id] / t.budget) * 100)}%</span>
                    </span>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      {/* Dashboard grid */}
      <div className="dash">
        {/* By tag — donut */}
        <div className="card col-5">
          <div className="card-section">
            By tag
            <span className="eyebrow">{tagData.length} categories</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '180px 1fr', gap: 22, alignItems: 'center' }}>
            <Donut
              data={tagData}
              size={180}
              thickness={20}
              centerLabel="Spent"
              centerValue={fmtCompact(expensesTotal)}
            />
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {tagData.slice(0, 6).map(d => (
                <div key={d.tagId} className="between" style={{ fontSize: 12 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <span style={{ width: 8, height: 8, background: d.color, borderRadius: 2, display: 'inline-block' }} />
                    <span style={{ color: 'var(--ink-2)' }}>{d.name}</span>
                  </div>
                  <span className="num" style={{ color: 'var(--ink)', fontSize: 12 }}>
                    {fmt(d.value, { cents: false })}
                  </span>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Recent expenses */}
        <div className="card col-7 list-card">
          <div className="card-section">
            Recent expenses
            <button className="btn ghost" onClick={() => setOpenModal('expense')}>
              + Add expense <span className="kbd">⌘N</span>
            </button>
          </div>
          {recent.map(e => {
            const t = tagById(tags, e.tagId);
            return (
              <div key={e.id} className="txn">
                <div className="txn-date">{monthDay(e.date)}</div>
                <div>
                  <div className="txn-merchant">{e.merchant}</div>
                  <div className="txn-meta">
                    <Tag tag={t} />
                    {e.note && <span className="muted">· {e.note}</span>}
                  </div>
                </div>
                <div></div>
                <div className="txn-amount expense num">{e.amount.toFixed(2)}</div>
              </div>
            );
          })}
        </div>

        {/* History sparkline */}
        <div className="card col-4">
          <div className="card-section">Last 6 months</div>
          <Sparkline data={sparkData} width={240} height={56} color="var(--terracotta)" />
          <div className="between" style={{ marginTop: 10 }}>
            <div>
              <div className="eyebrow">6-mo avg</div>
              <div className="num" style={{ fontSize: 17, marginTop: 2 }}>
                {fmt(sparkAvg, { cents: false })}
              </div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div className="eyebrow">{formatMonthKeyShort(activeMonth)}</div>
              <div className="num" style={{ fontSize: 17, marginTop: 2, color: 'var(--terracotta)' }}>
                {fmt(expensesTotal, { cents: false })}
              </div>
            </div>
          </div>
        </div>

        {/* Savings — pool + goals roll-up */}
        <div className="card col-4">
          <div className="card-section">
            Savings
            <span className="eyebrow">{(closedMonths || []).includes(activeMonth) ? 'closed' : 'open month'}</span>
          </div>
          <div style={{ marginBottom: 14 }}>
            <div className="muted" style={{ fontSize: 10.5, letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 4 }}>
              Total liquid
            </div>
            <div className="num" style={{ fontFamily: 'var(--font-display)', fontSize: 28, lineHeight: 1, color: 'var(--ink)' }}>
              {fmt((pool || 0) + goals.reduce((s, g) => s + g.saved, 0), { cents: false })}
            </div>
            <div className="row" style={{ marginTop: 8, gap: 14, fontSize: 11 }}>
              <span><span className="muted">Pool</span> <span className="num">{fmt(pool || 0, { cents: false })}</span></span>
              <span><span className="muted">In goals</span> <span className="num">{fmt(goals.reduce((s, g) => s + g.saved, 0), { cents: false })}</span></span>
            </div>
          </div>
          {goals.slice(0, 2).map(g => {
            const pct = (g.saved / g.target) * 100;
            return (
              <div key={g.id} style={{ marginBottom: 12 }}>
                <div className="between" style={{ marginBottom: 6 }}>
                  <span style={{ fontFamily: 'var(--font-display)', fontSize: 13, fontWeight: 500 }}>{g.name}</span>
                  <span className="num muted" style={{ fontSize: 10.5 }}>
                    {fmt(g.saved, { cents: false })} / {fmt(g.target, { cents: false })}
                  </span>
                </div>
                <div className="progress">
                  <div className="progress-bar good" style={{ width: pct + '%', background: TAG_COLORS[g.color] }} />
                </div>
              </div>
            );
          })}
        </div>

        {/* Tasks — upcoming */}
        <DashboardTasksCard tasks={tasks} family={family} setState={setState} setRoute={setRoute} />
      </div>
    </>
  );
}

function DashboardTasksCard({ tasks, family, setState, setRoute }) {
  const [filter, setFilter] = React.useState('all');
  const open = tasks.filter(t => !t.done);

  const weekStart = weekStartIso(isoDate(TODAY));
  const weekEnd = addDaysIso(weekStart, 6);
  const priorityRank = { III: 0, II: 1, I: 2 };

  const counts = {
    all:      open.length,
    week:     open.filter(t => t.dueDate && t.dueDate >= weekStart && t.dueDate <= weekEnd).length,
    priority: open.filter(t => (t.priority || 'II') === 'III').length,
    mine:     open.filter(t => t.memberId === 'self').length,
  };

  const filtered = open.filter(t => {
    if (filter === 'week')     return t.dueDate && t.dueDate >= weekStart && t.dueDate <= weekEnd;
    if (filter === 'priority') return (t.priority || 'II') === 'III';
    if (filter === 'mine')     return t.memberId === 'self';
    return true;
  });

  const sorted = [...filtered].sort((a, b) => {
    // Priority filter view: rank by priority first.
    if (filter === 'priority') {
      const pa = priorityRank[a.priority || 'II'] ?? 1;
      const pb = priorityRank[b.priority || 'II'] ?? 1;
      if (pa !== pb) return pa - pb;
    }
    if (a.dueDate && b.dueDate) return a.dueDate.localeCompare(b.dueDate);
    if (a.dueDate) return -1;
    if (b.dueDate) return 1;
    return 0;
  });
  const upcoming = sorted.slice(0, 5);
  const remaining = filtered.length - upcoming.length;

  const toggleDone = (taskId) => {
    setState(s => ({
      ...s,
      tasks: (s.tasks || []).map(t => t.id === taskId ? { ...t, done: !t.done } : t),
    }));
  };

  return (
    <div className="card col-4 list-card">
      <div className="card-section">
        Tasks
        <button className="btn ghost" onClick={() => setRoute && setRoute('tasks')}
          style={{ fontSize: 11 }}>
          Open all →
        </button>
      </div>
      <div className="dash-task-filter">
        {[
          { id: 'all',      label: 'All' },
          { id: 'week',     label: 'This week' },
          { id: 'priority', label: 'Priority' },
          { id: 'mine',     label: 'Mine' },
        ].map(f => (
          <button key={f.id}
            className={`dash-task-filter-btn ${filter === f.id ? 'active' : ''}`}
            onClick={() => setFilter(f.id)}>
            <span>{f.label}</span>
            <span className="dash-task-filter-count">{counts[f.id]}</span>
          </button>
        ))}
      </div>
      {upcoming.length === 0 ? (
        <div className="muted" style={{ fontSize: 12, padding: '6px 2px' }}>
          {filter === 'week'     ? 'Nothing due this week.'
           : filter === 'priority' ? 'No high-priority tasks.'
           : filter === 'mine'     ? 'Nothing assigned to you.'
           : 'Nothing on the list — head to Tasks to add something.'}
        </div>
      ) : (
        upcoming.map(t => {
          const due = formatDue(t.dueDate, t.done);
          const member = t.memberId ? family.find(m => m.id === t.memberId) : null;
          const subs = t.subtasks || [];
          const subDone = subs.filter(s => s.done).length;
          return (
            <div key={t.id} className="dash-task-row">
              <button className={`task-check small ${t.done ? 'on' : ''}`}
                onClick={(e) => { e.stopPropagation(); toggleDone(t.id); }}
                aria-label={t.done ? 'Mark not done' : 'Mark done'}
                title={t.done ? 'Mark not done' : 'Mark done'}>
                {t.done ? '✓' : ''}
              </button>
              <button className="dash-task-title-btn"
                onClick={() => setRoute && setRoute('tasks')}
                title="Open in Tasks">
                {t.title}
              </button>
              <div className="dash-task-meta">
                {(() => {
                  const p = t.priority || 'II';
                  const tone = p === 'I' ? 'low' : p === 'III' ? 'high' : 'med';
                  return <span className={`task-prio prio-${tone}`} title={`Priority ${p}`}>{p}</span>;
                })()}
                {due && <span className={`task-due ${due.tone}`}>{due.label}</span>}
                {subs.length > 0 && (
                  <span className="muted mono" style={{ fontSize: 10.5 }}>{subDone}/{subs.length}</span>
                )}
                {member && (
                  <span className="dash-task-member"
                    style={{ background: TAG_COLORS[member.color] }}
                    title={member.name}>{nameInitials(member.name)}</span>
                )}
              </div>
            </div>
          );
        })
      )}
      {remaining > 0 && (
        <div className="muted mono" style={{ fontSize: 10.5, marginTop: 8, textAlign: 'right' }}>
          +{remaining} more
        </div>
      )}
    </div>
  );
}

Object.assign(window, { NAV, DashboardScreen });
