// Dashboard — KPIs, Sankey, area chart, recent activity, top categories.

const KPICard = ({ label, value, delta, deltaLabel, accent, icon: Ico, sub }) => {
  const animated = useCountUp(value);
  return (
    <div className="card card-pad hov fade-up">
      <div className="row-between" style={{marginBottom: 14}}>
        <div className="row" style={{gap:8}}>
          {Ico && <div style={{
            width:30, height:30, borderRadius:9,
            background: accent ? `var(--${accent}-soft, var(--surface-2))` : 'var(--surface-2)',
            color: accent ? `var(--${accent}-deep, var(--ink-2))` : 'var(--ink-2)',
            display:'inline-flex', alignItems:'center', justifyContent:'center'
          }}>
            <Ico size={15}/>
          </div>}
          <span style={{fontSize:13, color:'var(--ink-3)', fontWeight:500}}>{label}</span>
        </div>
        {delta != null && (
          <span className={`kpi-delta ${delta > 0 ? 'up' : delta < 0 ? 'down' : 'neutral'}`}>
            {delta > 0 ? <IArrowUp size={11}/> : delta < 0 ? <IArrowDown size={11}/> : null}
            {Math.abs(delta).toFixed(1)}%
          </span>
        )}
      </div>
      <div className="kpi-value serif">{fmtZAR(animated, {cents: false})}</div>
      {sub && <div style={{fontSize:12, color:'var(--ink-3)', marginTop:6}}>{sub}</div>}
      {deltaLabel && <div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:4}}>{deltaLabel}</div>}
    </div>
  );
};

const PageDashboard = ({ setPage }) => {
  const { state, derived, loadDemo } = useAppState();
  const { income, expense, net, totalDebt, totalGoals, categoryBreakdown, months } = derived;

  const hasData = state.transactions.length > 0;
  const debtMin = state.debts.reduce((a, d) => a + d.minimum, 0);
  const savingsRate = income > 0 ? Math.max(0, (net / income)) : 0;

  // Compare to previous month
  const thisMo = months[months.length - 1] || { income: 0, expense: 0 };
  const prevMo = months[months.length - 2] || { income: 0, expense: 0 };
  const expenseDelta = prevMo.expense ? ((thisMo.expense - prevMo.expense) / prevMo.expense) * 100 : 0;
  const incomeDelta = prevMo.income ? ((thisMo.income - prevMo.income) / prevMo.income) * 100 : 0;

  if (!hasData) {
    return (
      <div className="fade-up">
        <DashboardHeader />
        <div className="empty" style={{marginTop: 20}}>
          <div className="empty-icon"><IWallet size={24}/></div>
          <h3 className="serif" style={{fontSize:24}}>Let's build your budget</h3>
          <p>Start by adding your income and expenses, or load demo data to see how it works with realistic South African figures.</p>
          <div className="row" style={{justifyContent:'center', gap:10}}>
            <button className="btn btn-primary" onClick={() => setPage('transactions')}>
              <IPlus size={14}/> Add transactions
            </button>
            <button className="btn" onClick={loadDemo}>
              <IPlay size={14}/> Load demo data
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div>
      <DashboardHeader/>

      {/* Coach card */}
      <CoachCard/>

      {/* KPIs */}
      <div className="grid stagger" style={{gridTemplateColumns:'repeat(4, 1fr)', marginTop:20}}>
        <KPICard label="Income (this month)" value={thisMo.income} delta={incomeDelta} icon={IArrowDown} accent="mint" sub="From all sources"/>
        <KPICard label="Spending (this month)" value={thisMo.expense} delta={-expenseDelta} icon={IArrowUp} accent="coral" sub={`${categoryBreakdown.length} categories`}/>
        <KPICard label="Net" value={thisMo.income - thisMo.expense} icon={IBolt} accent="amber" sub={`Saving rate: ${(savingsRate * 100).toFixed(0)}%`}/>
        <KPICard label="Total debt" value={totalDebt} icon={IDebt} sub={`Minimums: ${fmtZAR(debtMin, {cents:false})}/mo`}/>
      </div>

      {/* Sankey */}
      <div className="card card-pad-lg fade-up" style={{marginTop:20, animationDelay:'0.2s'}}>
        <div className="card-title">
          <span>Where your money flows · {monthNames[today().getMonth()]}</span>
          <span className="pill"><span className="dot" style={{background:'var(--mint-deep)'}}></span> {fmtZARShort(income)} in → {fmtZARShort(expense)} out</span>
        </div>
        <SankeyFlow
          income={thisMo.income}
          expenseByCategory={categoryBreakdown.slice(0, 6)}
          savings={Math.max(0, thisMo.income - thisMo.expense - debtMin)}
          debtPayments={debtMin}
        />
      </div>

      {/* Cashflow + Donut */}
      <div className="grid" style={{gridTemplateColumns:'1.6fr 1fr', marginTop:20, gap:20}}>
        <div className="card card-pad-lg fade-up" style={{animationDelay:'0.3s'}}>
          <div className="card-title">
            <span>Cashflow · last 6 months</span>
            <div className="row" style={{gap:14, fontSize:11, color:'var(--ink-3)'}}>
              <span className="row" style={{gap:5}}><span className="dot" style={{background:'var(--mint-deep)'}}></span>Income</span>
              <span className="row" style={{gap:5}}><span className="dot" style={{background:'var(--coral)'}}></span>Spending</span>
            </div>
          </div>
          <AreaChart months={months} height={220}/>
        </div>
        <div className="card card-pad-lg fade-up" style={{animationDelay:'0.4s'}}>
          <div className="card-title">
            <span>Spend by category</span>
          </div>
          <Donut data={categoryBreakdown.slice(0, 6)} centerLabel="Total spend" centerSub={`${monthNames[today().getMonth()]} ${today().getFullYear()}`}/>
          <div style={{marginTop:18, display:'flex', flexDirection:'column', gap:8}}>
            {categoryBreakdown.slice(0, 4).map(c => (
              <div key={c.id} className="row-between" style={{fontSize:12.5}}>
                <div className="row" style={{gap:8}}>
                  <span className="dot" style={{background:`var(${c.cssVar})`}}></span>
                  {c.label}
                </div>
                <span className="mono" style={{color:'var(--ink-3)'}}>{(c.pct * 100).toFixed(0)}%</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Recent + Goals progress */}
      <div className="grid" style={{gridTemplateColumns:'1.4fr 1fr', marginTop:20, gap:20}}>
        <div className="card fade-up" style={{animationDelay:'0.5s'}}>
          <div className="card-pad-lg" style={{paddingBottom:0}}>
            <div className="card-title row-between">
              <span>Recent transactions</span>
              <button className="btn btn-ghost btn-sm" onClick={() => setPage('transactions')}>View all <IArrowRight size={11}/></button>
            </div>
          </div>
          <div style={{padding:'0 22px 14px'}}>
            {state.transactions.slice(0, 6).map((t, i) => {
              const cat = t.type === 'expense' ? categoryById(t.category) : null;
              const member = state.members.find(m => m.id === t.memberId);
              return (
                <div key={t.id} className="row-between" style={{padding:'12px 0', borderBottom: i === 5 ? 'none' : '1px solid var(--line-2)', animation:`fadeUp 0.4s ${i * 0.04}s both`}}>
                  <div className="row" style={{gap:12}}>
                    <div style={{
                      width:34, height:34, borderRadius:10,
                      background: t.type === 'income' ? 'var(--mint-soft)' : (cat ? `var(${cat.cssVar.replace(')',`-soft)`).replace('-soft-soft','-soft')}` : 'var(--surface-2)'),
                      color: t.type === 'income' ? 'var(--mint-deep)' : `var(${cat?.cssVar || '--ink-2'})`,
                      display:'inline-flex', alignItems:'center', justifyContent:'center'
                    }}>
                      {t.type === 'income' ? <IArrowDown size={14}/> : <IArrowUp size={14}/>}
                    </div>
                    <div>
                      <div style={{fontSize:13.5, fontWeight:500}}>{t.note || (t.type === 'income' ? 'Income' : cat?.label)}</div>
                      <div style={{fontSize:11.5, color:'var(--ink-3)'}}>{cat?.label || (t.type === 'income' ? 'Income' : '')} · {fmtDate(new Date(t.date))} {state.mode === 'household' && member && `· ${member.name}`}</div>
                    </div>
                  </div>
                  <div className="mono" style={{fontWeight:500, color: t.type === 'income' ? 'var(--mint-deep)' : 'var(--ink)'}}>
                    {t.type === 'income' ? '+' : '−'}{fmtZAR(t.amount, {cents:false}).replace('R ','R ')}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="card card-pad-lg fade-up" style={{animationDelay:'0.55s'}}>
          <div className="card-title row-between">
            <span>Savings goals</span>
            <button className="btn btn-ghost btn-sm" onClick={() => setPage('savings')}>Manage <IArrowRight size={11}/></button>
          </div>
          {state.goals.length === 0 ? (
            <div style={{fontSize:13, color:'var(--ink-3)', padding:'12px 0'}}>No goals yet.</div>
          ) : state.goals.slice(0, 3).map((g, i) => {
            const pct = g.target ? Math.min(1, g.saved / g.target) : 0;
            return (
              <div key={g.id} style={{marginTop: i === 0 ? 6 : 18, animation:`fadeUp 0.4s ${i*0.06}s both`}}>
                <div className="row-between" style={{marginBottom:8}}>
                  <div style={{fontSize:13.5, fontWeight:500}}>{g.name}</div>
                  <div className="mono" style={{fontSize:12, color:'var(--ink-3)'}}>{fmtZARShort(g.saved)} / {fmtZARShort(g.target)}</div>
                </div>
                <div className="progress-track">
                  <div className="progress-fill" style={{width: `${pct * 100}%`, background:'var(--mint)'}}/>
                </div>
                <div style={{fontSize:11, color:'var(--ink-3)', marginTop:6}}>{(pct*100).toFixed(0)}% complete</div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

const DashboardHeader = () => {
  const { state } = useAppState();
  const { user } = useAuth();
  const firstName = (() => {
    const meta = user?.user_metadata;
    if (meta?.full_name) return meta.full_name.split(' ')[0];
    if (meta?.name) return meta.name.split(' ')[0];
    const prefix = (user?.email || '').split('@')[0].split(/[._+\-]/)[0].replace(/\d+$/, '');
    return prefix ? prefix.charAt(0).toUpperCase() + prefix.slice(1).toLowerCase() : 'there';
  })();
  const greet = (() => {
    const h = new Date().getHours();
    if (h < 12) return 'Good morning';
    if (h < 17) return 'Good afternoon';
    return 'Good evening';
  })();
  return (
    <div className="topbar">
      <div>
        <h1 className="page-title">{greet}, <span className="serif">{firstName}</span></h1>
        <div className="page-sub">Here's where your money sits, {fmtDate(today())}</div>
      </div>
      <div className="row" style={{gap:12}}></div>
    </div>
  );
};

const CoachCard = () => {
  const { derived, state } = useAppState();
  const { income, expense, totalDebt, months } = derived;
  const thisMo = months[months.length - 1] || { income: 0, expense: 0 };
  const prevMo = months[months.length - 2] || { income: 0, expense: 0 };

  let title = "Nice work — you're on track this month";
  let body = "Keep this up and you'll hit your savings goal sooner than expected.";
  let stat = '';

  if (prevMo.expense && thisMo.expense < prevMo.expense) {
    const diff = prevMo.expense - thisMo.expense;
    const pct = (diff / prevMo.expense) * 100;
    title = `You're spending ${pct.toFixed(0)}% less than last month`;
    body = `That's ${fmtZARShort(diff)} kept in your pocket. Send it to your emergency fund?`;
    stat = `−${fmtZARShort(diff)}`;
  } else if (totalDebt > income * 5) {
    title = "Let's chip away at that debt";
    body = "Your debt is high vs your income — the avalanche method could save you the most. Have a look at the debt page.";
    stat = fmtZARShort(totalDebt);
  } else if (thisMo.income > thisMo.expense) {
    const surplus = thisMo.income - thisMo.expense;
    const pct = (surplus / thisMo.income) * 100;
    title = `You saved ${pct.toFixed(0)}% of your income this month`;
    body = `${fmtZARShort(surplus)} surplus. Sweet — let's put it to work.`;
    stat = `+${fmtZARShort(surplus)}`;
  }

  return (
    <div className="coach fade-up" style={{animationDelay:'0.05s'}}>
      <div className="row" style={{gap:10, marginBottom:8, opacity:0.85, position:'relative'}}>
        <ISparkle size={14}/>
        <span style={{fontSize:11, textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:500}}>Insight of the day</span>
      </div>
      <div className="row-between" style={{position:'relative', flexWrap:'wrap', gap:14}}>
        <div style={{flex:'1 1 60%', minWidth: 280}}>
          <div className="serif" style={{fontSize:26, lineHeight:1.2, letterSpacing:'-0.01em'}}>{title}</div>
          <div style={{fontSize:13, opacity:0.75, marginTop:8, maxWidth:480}}>{body}</div>
        </div>
        {stat && (
          <div className="mono" style={{fontSize:36, fontWeight:300, letterSpacing:'-0.02em', position:'relative'}}>{stat}</div>
        )}
      </div>
    </div>
  );
};

Object.assign(window, { PageDashboard, KPICard, CoachCard });
