﻿// BillyHub generated split file. Keep script order in Bills Manager.html.
function DayPicker({ value, onChange }) {
  return (
    <div style={{ display:'grid', gridTemplateColumns:'repeat(7,1fr)', gap:5, marginTop:8 }}>
      {Array.from({ length: 31 }, (_, i) => i + 1).map(d => (
        <button type="button" key={d} onClick={() => onChange(d)} style={{
          padding:'9px 0', borderRadius:10, cursor:'pointer', fontWeight:700, fontSize:'0.86rem',
          border: value === d ? 'none' : '1px solid var(--line)',
          background: value === d ? 'linear-gradient(135deg,var(--navy),var(--teal))' : 'var(--surface-strong)',
          color: value === d ? 'white' : 'var(--text)',
        }}>{d}</button>
      ))}
    </div>
  );
}

// â”€â”€ Bill Modal â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function BillModal({ bill, onSave, onClose, onDeleteRequest }) {
  const isNew = !bill.id;
  const [form, setForm] = useState({
    name: '', amount: '', frequency: 'monthly', dueDay: 1,
    startDate: todayISO(), autoPay: false, notes: '',
    ...bill, amount: bill.amount != null ? String(bill.amount) : '',
    linkedDebtId: '',
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSubmit = e => {
    e.preventDefault();
    if (!form.name.trim() || !form.amount) return;
    onSave({
      ...form,
      id: bill.id || uid(),
      amount: parseFloat(form.amount) || 0,
      dueDay: parseInt(form.dueDay) || 1,
      linkedDebtId: '',
    });
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">{isNew ? 'Add Bill' : 'Edit Bill'}</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            <div className="modal-grid">
              <div className="field full">
                <span>Bill Name</span>
                <input type="text" placeholder="e.g. Rent, Netflix..." value={form.name}
                  onChange={e => set('name', e.target.value)} required autoFocus />
              </div>
              <div className="field">
                <span>Amount ($)</span>
                <input type="number" step="0.01" min="0" placeholder="0.00"
                  value={form.amount} onChange={e => set('amount', e.target.value)} className="money-input" required />
              </div>
              <div className="field">
                <span>Frequency</span>
                <div className="select-shell">
                  <select value={form.frequency} onChange={e => set('frequency', e.target.value)}>
                    {FREQ.map(f => <option key={f.value} value={f.value}>{f.label}</option>)}
                  </select>
                </div>
              </div>
              {form.frequency === 'monthly' ? (
                <div className="field full">
                  <span>Due Day of Month</span>
                  <DayPicker value={parseInt(form.dueDay)||1} onChange={d => set('dueDay', d)} />
                </div>
              ) : (
                <div className="field full">
                  <span>{form.frequency === 'one-time' ? 'Due Date' : 'Start / Anchor Date'}</span>
                  <input type="date" value={form.startDate} onChange={e => set('startDate', e.target.value)} />
                </div>
              )}
              <div className="field full">
                <span>Notes</span>
                <input type="text" placeholder="Optional notes..." value={form.notes} onChange={e => set('notes', e.target.value)} />
              </div>
              <div className="full">
                <label className="toggle">
                  <input type="checkbox" checked={form.autoPay} onChange={e => set('autoPay', e.target.checked)} />
                  <span className="toggle-track"></span>
                  <span className="toggle-label">Auto-pay enabled</span>
                </label>
              </div>
            </div>
          </div>
          <div className="modal-footer" style={{ justifyContent: isNew ? 'flex-end' : 'space-between' }}>
            {!isNew && (
              <button type="button" className="danger-ghost"
                onClick={() => onDeleteRequest?.(bill)}>
                Delete Bill
              </button>
            )}
            <div style={{ display:'flex', gap:10 }}>
              <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
              <button type="submit" className="primary-button">{isNew ? '+ Add Bill' : 'Save Changes'}</button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}

// â”€â”€ Debt Modal â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function DebtModal({ debt, onSave, onClose, onDeleteRequest }) {
  const isNew = !debt || !debt.id;
  const safeDebt = debt || {};
  const [form, setForm] = useState({
    name: safeDebt.name || '',
    balance: safeDebt.balance != null ? String(safeDebt.balance) : '',
    apr: safeDebt.apr != null ? String(safeDebt.apr) : '',
    minPayment: safeDebt.minPayment != null ? String(safeDebt.minPayment) : '',
    category: debtCategory(safeDebt),
    notes: safeDebt.notes || '',
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSubmit = e => {
    e.preventDefault();
    if (!form.name.trim()) return;
    const saved = {
      id: safeDebt.id || uid(),
      name: form.name.trim(),
      balance: parseFloat(form.balance) || 0,
      apr: parseFloat(form.apr) || 0,
      minPayment: parseFloat(form.minPayment) || 0,
      category: form.category,
      notes: form.notes,
    };
    onSave(saved);
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">{isNew ? 'Add Debt' : 'Edit Debt'}</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            <div className="modal-grid">
              <div className="field full">
                <span>Debt Name</span>
                <input type="text" placeholder="e.g. Visa Card, Student Loan..."
                  value={form.name} onChange={e => set('name', e.target.value)} required autoFocus />
              </div>
              <div className="field">
                <span>Current Balance ($)</span>
                <input type="number" step="0.01" min="0" placeholder="0.00"
                  value={form.balance} onChange={e => set('balance', e.target.value)} className="money-input" />
              </div>
              <div className="field">
                <span>APR (%)</span>
                <input type="number" step="0.01" min="0" max="100" placeholder="e.g. 24.99"
                  value={form.apr} onChange={e => set('apr', e.target.value)} />
              </div>
              <div className="field">
                <span>Min. Monthly Payment ($)</span>
                <input type="number" step="0.01" min="0" placeholder="0.00"
                  value={form.minPayment} onChange={e => set('minPayment', e.target.value)} className="money-input" />
              </div>
              <div className="field">
                <span>Category</span>
                <div className="select-shell">
                  <select value={form.category} onChange={e => set('category', e.target.value)}>
                    {DEBT_CATEGORIES.map(category => <option key={category} value={category}>{category}</option>)}
                  </select>
                </div>
                <input type="text" placeholder="Optional..." value={form.notes} onChange={e => set('notes', e.target.value)} />
              </div>
            </div>
          </div>
          <div className="modal-footer" style={{ justifyContent: isNew ? 'flex-end' : 'space-between' }}>
            {!isNew && (
              <button type="button" className="danger-ghost"
                onClick={() => onDeleteRequest?.(safeDebt)}>
                Delete Debt
              </button>
            )}
            <div style={{ display:'flex', gap:10 }}>
              <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
              <button type="submit" className="primary-button">{isNew ? '+ Add Debt' : 'Save Changes'}</button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}

// â”€â”€ Top Bar â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function relativeStamp(iso) {
  if (!iso) return 'Not saved yet';
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return 'Not saved yet';
  const diff = Math.max(0, Date.now() - date.getTime());
  const minute = 60000;
  if (diff < minute) return 'Just now';
  if (diff < minute * 60) return `${Math.floor(diff / minute)}m ago`;
  const hours = Math.floor(diff / (minute * 60));
  if (hours < 24) return `${hours}h ago`;
  return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

function AuthScreen({ onSubmit, mode, setMode, loading, error, notice }) {
  const [form, setForm] = useState({ firstName: '', email: '', password: '' });
  const isSignup = mode === 'signup';
  const set = (key, value) => setForm(current => ({ ...current, [key]: value }));
  const handleSubmit = e => {
    e.preventDefault();
    onSubmit(form);
  };

  return (
    <div className="auth-shell">
      <div className="auth-card">
        <div className="auth-brand">
          <img src="Billy Hub Logo.png" alt="BillyHub logo" className="auth-logo" />
          <div>
            <span>BillyHub</span>
            <h1>{isSignup ? 'Create your account' : 'Welcome back'}</h1>
          </div>
        </div>
        <p className="auth-copy">
          {isSignup
            ? 'Start with a fresh BillyHub workspace that saves to your account.'
            : 'Sign in to load your saved bills, debts, budget, and payment history.'}
        </p>
        <form className="auth-form" onSubmit={handleSubmit}>
          {isSignup && (
            <label className="field">
              <span>First Name</span>
              <input type="text" autoComplete="given-name" value={form.firstName} onChange={e => set('firstName', e.target.value)} required />
            </label>
          )}
          <label className="field">
            <span>Email</span>
            <input type="email" autoComplete="email" value={form.email} onChange={e => set('email', e.target.value)} required />
          </label>
          <label className="field">
            <span>Password</span>
            <input type="password" autoComplete={isSignup ? 'new-password' : 'current-password'} value={form.password} onChange={e => set('password', e.target.value)} minLength="6" required />
          </label>
          {error && <div className="auth-alert is-error">{error}</div>}
          {notice && <div className="auth-alert">{notice}</div>}
          <button type="submit" className="primary-button auth-submit" disabled={loading}>
            {loading ? 'Please wait...' : isSignup ? 'Create Account' : 'Log In'}
          </button>
        </form>
        <button type="button" className="auth-switch" onClick={() => setMode(isSignup ? 'login' : 'signup')}>
          {isSignup ? 'Already have an account? Log in' : 'Need an account? Create one'}
        </button>
      </div>
    </div>
  );
}

function TopBar({ isSettingsActive, onOpenSettings, userEmail, onLogout }) {
  return (
      <div className="topbar">
        <div className="brand-lockup">
          <img
            src="Billy Hub Logo.png"
            alt="BillyHub logo"
            className="brand-logo"
          />
          <span style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:700, fontSize:'1.18rem' }}>BillyHub</span>
        </div>
        <div className="topbar-actions">
          {userEmail && <span className="account-pill">{userEmail}</span>}
          <button
            type="button"
            className={`settings-button${isSettingsActive ? ' is-active' : ''}`}
            onClick={onOpenSettings}
          >
            Settings
          </button>
          <button type="button" className="settings-button logout-button" onClick={onLogout}>
            Log Out
          </button>
        </div>
    </div>
  );
}

function PaymentModal({ payment, showCents, onSave, onClose }) {
  const [amount, setAmount] = useState(payment.amount || '');
  const bill = payment.bill || {};
  const dueDate = payment.dueDate;
  const handleSubmit = e => {
    e.preventDefault();
    onSave(parseFloat(amount));
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel payment-modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">Log payment</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            <div className="payment-modal-summary">
              <strong>{bill.name}</strong>
              <span>{shortDate(dueDate)} due - {fmt(parseFloat(bill.amount) || 0, showCents)}</span>
            </div>
            <label className="field full">
              <span>Amount paid ($)</span>
              <input
                type="number"
                min="0"
                step="0.01"
                value={amount}
                onChange={e => setAmount(e.target.value)}
                autoFocus
              />
            </label>
          </div>
          <div className="modal-footer" style={{ justifyContent:'flex-end' }}>
            <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
            <button type="submit" className="primary-button">Save Payment</button>
          </div>
        </form>
      </div>
    </div>
  );
}

function QuickEntryModal({ entry, onSave, onClose }) {
  const [mode, setMode] = useState(entry.mode || 'expense');
  const isFunding = mode === 'funding';
  const [form, setForm] = useState({
    category: entry.category || 'Gas',
    amount: entry.amount || '',
    note: entry.note || '',
  });
  const set = (k, v) => setForm(current => ({ ...current, [k]: v }));
  const handleSubmit = e => {
    e.preventDefault();
    onSave({
      ...entry,
      ...form,
      mode,
      amount: parseFloat(form.amount),
      note: form.note.trim(),
      category: form.category || 'Other',
    });
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel payment-modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">{isFunding ? 'Add money' : 'Quick Add Expense'}</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            {!isFunding && (
              <label className="field full">
                <span>Category</span>
                <div className="select-shell">
                  <select value={form.category} onChange={e => set('category', e.target.value)}>
                    {['Gas','Groceries','Food','Entertainment','Household','Other'].map(x => <option key={x}>{x}</option>)}
                  </select>
                </div>
              </label>
            )}
            <label className="field full">
              <span>Amount ($)</span>
              <input
                type="number"
                min="0"
                step="0.01"
                value={form.amount}
                onChange={e => set('amount', e.target.value)}
                autoFocus
              />
            </label>
            <label className="field full">
              <span>{isFunding ? 'Source / Note' : 'Note'}</span>
              <input
                type="text"
                placeholder={isFunding ? 'Optional source or note' : 'Optional'}
                value={form.note}
                onChange={e => set('note', e.target.value)}
              />
            </label>
          </div>
          <div className="modal-footer" style={{ justifyContent:'space-between' }}>
            <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
              {!isFunding ? (
                <button type="button" className="ghost-button" onClick={() => setMode('funding')}>+ Add Money</button>
              ) : (
                <button type="button" className="ghost-button" onClick={() => setMode('expense')}>+ Add Expense</button>
              )}
            </div>
            <div style={{ display:'flex', gap:10 }}>
              <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
            <button type="submit" className="primary-button">{isFunding ? '+ Add Money' : '+ Add Expense'}</button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}

function ActivityModal({ item, onSave, onDelete, onClose }) {
  const isExpense = item.activityType === 'expense';
  const isFunding = item.activityType === 'funding';
  const [form, setForm] = useState({
    amount: item.amount != null ? String(item.amount) : '',
    category: item.category || 'Other',
    note: item.note || '',
  });
  const set = (k, v) => setForm(current => ({ ...current, [k]: v }));
  const handleSubmit = e => {
    e.preventDefault();
    onSave({
      ...item,
      ...form,
      amount: parseFloat(form.amount),
      category: form.category || 'Other',
      note: form.note.trim(),
    });
  };
  const subtitle = isExpense
    ? `${item.category || 'Expense'} - ${shortDate(parseLocalDate(item.date))}`
    : isFunding
      ? `Added money - ${shortDate(parseLocalDate(item.date))}`
      : `${item.billName} - ${shortDate(parseLocalDate(item.dueDate || item.date))}`;

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel payment-modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">Edit activity</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            <div className="payment-modal-summary">
              <strong>{item.title || item.billName || 'Activity'}</strong>
              <span>{subtitle}</span>
            </div>
            {(isExpense || isFunding) && !isFunding && (
              <label className="field full">
                <span>Category</span>
                <div className="select-shell">
                  <select value={form.category} onChange={e => set('category', e.target.value)}>
                    {['Gas','Groceries','Food','Entertainment','Household','Other'].map(x => <option key={x}>{x}</option>)}
                  </select>
                </div>
              </label>
            )}
            <label className="field full">
              <span>Amount ($)</span>
              <input
                type="number"
                min="0"
                step="0.01"
                value={form.amount}
                onChange={e => set('amount', e.target.value)}
                autoFocus
              />
            </label>
            {(isExpense || isFunding) && (
              <label className="field full">
                <span>{isFunding ? 'Source / Note' : 'Note'}</span>
                <input
                  type="text"
                  placeholder="Optional"
                  value={form.note}
                  onChange={e => set('note', e.target.value)}
                />
              </label>
            )}
          </div>
          <div className="modal-footer" style={{ justifyContent:'space-between' }}>
            <button type="button" className="danger-ghost" onClick={() => { onDelete(item); onClose(); }}>
              Delete Entry
            </button>
            <div style={{ display:'flex', gap:10 }}>
              <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
              <button type="submit" className="primary-button">Save Changes</button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}

function ConfirmModal({ title, body, confirmLabel = 'Confirm', cancelLabel = 'Cancel', tone = 'danger', onConfirm, onClose }) {
  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel confirm-modal-panel">
        <div className="modal-header">
          <h2 className="modal-title">{title}</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <div className="modal-body">
          <div className="confirm-modal-copy">
            <p>{body}</p>
          </div>
        </div>
        <div className="modal-footer" style={{ justifyContent:'flex-end' }}>
          <button type="button" className="ghost-button" onClick={onClose}>{cancelLabel}</button>
          <button
            type="button"
            className={tone === 'danger' ? 'danger-ghost' : 'primary-button'}
            onClick={() => { onConfirm?.(); onClose(); }}
          >
            {confirmLabel}
          </button>
        </div>
      </div>
    </div>
  );
}

function ImportPreviewModal({ preview, onConfirm, onClose }) {
  const rows = [
    ['Bills', preview.current.bills, preview.incoming.bills],
    ['Debts', preview.current.debts, preview.incoming.debts],
    ['Payments', preview.current.payments, preview.incoming.payments],
    ['Expenses', preview.current.expenses, preview.incoming.expenses],
    ['Money added', preview.current.funding, preview.incoming.funding],
  ];

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel import-preview-panel">
        <div className="modal-header">
          <h2 className="modal-title">Preview import</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">x</button>
        </div>
        <div className="modal-body">
          <div className="import-preview-summary">
            <strong>{preview.fileName || 'BillyHub backup'}</strong>
            <span>{preview.exportedAt ? `Exported ${new Date(preview.exportedAt).toLocaleString()}` : 'No export date found'}</span>
          </div>
          <div className="import-preview-grid">
            <div className="import-preview-head">Data</div>
            <div className="import-preview-head">Current</div>
            <div className="import-preview-head">Import</div>
            {rows.map(([label, current, incoming]) => (
              <React.Fragment key={label}>
                <div>{label}</div>
                <strong>{current}</strong>
                <strong>{incoming}</strong>
              </React.Fragment>
            ))}
          </div>
          <p className="import-preview-warning">
            Importing will replace the matching BillyHub data on this device. Export a backup first if you want a copy of the current state.
          </p>
        </div>
        <div className="modal-footer" style={{ justifyContent:'flex-end' }}>
          <button type="button" className="ghost-button" onClick={onClose}>Cancel</button>
          <button type="button" className="primary-button" onClick={onConfirm}>Import backup</button>
        </div>
      </div>
    </div>
  );
}

// â”€â”€ Hero â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function Hero({ bills, debts, payPeriod, payday = {}, budget = {}, paymentLog = [], fundingLog = [], expenses = [], userFirstName = '', onQuickAddExpense }) {
  const today = new Date();
  const todayStart = new Date(today); todayStart.setHours(0,0,0,0);
  const totalDebt = debts.reduce((s,d) => s + d.balance, 0);
  const period = getCurrentPayPeriod(payPeriod.date1, payPeriod.date2);
  const periodEntries = period ? bills
    .map(b => ({ b, d: getNextDue(b, period.start) }))
    .filter(({ d }) => d && d >= period.start && d <= period.end) : [];
  const unpaidEntries = periodEntries
    .filter(({ b, d }) => !isOccurrencePaid(b, d) && !isOccurrencePrepaid(b, d))
    .sort((a,b) => a.d - b.d);
  const periodTotal = unpaidEntries.reduce((s, { b }) => s + (parseFloat(b.amount) || 0), 0);
  const originalPeriodTotal = periodEntries.reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const prepaidPeriodTotal = periodEntries
    .filter(({ b, d }) => isOccurrencePrepaid(b, d))
    .reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const currentPayPeriodOption = payday?.autoEnabled
    ? getPayPeriodOptions(payday, todayStart, 1, 8).find(option => option.isCurrent)
    : null;
  const currentPayPeriodKey = currentPayPeriodOption ? `${toLocalISO(currentPayPeriodOption.start)}_${toLocalISO(currentPayPeriodOption.end)}` : '';
  const paycheckOverrides = budget.paycheckOverrides || {};
  const overrideValue = currentPayPeriodKey ? paycheckOverrides[currentPayPeriodKey] : '';
  const defaultCheckAmount = parseFloat(payday?.paycheckAmount || budget.amount) || 0;
  const paycheckAmount = overrideValue !== '' && Number.isFinite(parseFloat(overrideValue))
    ? parseFloat(overrideValue)
    : defaultCheckAmount;
  const accountLeftAfterPrepaid = paycheckAmount - Math.max(0, originalPeriodTotal - prepaidPeriodTotal);
  const nextBill = bills
    .map(b => ({ b, d: getNextDue(b, todayStart) }))
    .filter(({ d }) => d)
    .sort((a,b) => a.d - b.d)[0];
  const nextBillGroup = nextBill
    ? bills
      .map(b => ({ b, d: getNextDue(b, todayStart) }))
      .filter(({ d }) => d && occurrenceKey(d) === occurrenceKey(nextBill.d))
      .sort((a,b) => a.b.name.localeCompare(b.b.name))
    : [];
  const nextBillTotal = nextBillGroup.reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const nextBillNames = nextBillGroup.map(({ b }) => b.name);
  const nextBillNameLabel = nextBillNames.length > 2
    ? `${nextBillNames.slice(0, 2).join(' + ')} + ${nextBillNames.length - 2} more`
    : nextBillNames.join(' + ');
  const nextBillLabel = nextBillGroup.length > 1
    ? `${nextBillNameLabel} ${fmt(nextBillTotal,false)}`
    : nextBill ? `${nextBill.b.name} ${fmt(nextBill.b.amount,false)}` : 'None';
  const periodLabel = period ? `${shortDate(period.start)} - ${shortDate(period.end)}` : 'Set pay dates ->';
  const payDates = [payPeriod.date1, payPeriod.date2]
    .map(v => parseLocalDate(v))
    .filter(d => d && !Number.isNaN(d.getTime()))
    .sort((a,b) => a - b);
  const nextPayDate = payDates.find(d => d >= todayStart) || null;
  const nextPayDays = nextPayDate ? Math.ceil((nextPayDate - todayStart) / 86400000) : null;
  const nextPayText = nextPayDate
    ? `${shortDate(nextPayDate)} - ${nextPayDays === 0 ? 'Today' : nextPayDays === 1 ? 'Tomorrow' : `in ${nextPayDays} days`}`
    : 'Set pay dates';

  return (
    <div className="hero hero-compact">
      <div className="hero-copy">
        <p className="section-kicker hero-kicker">BillyHub command center</p>
        <h2 style={{ margin:'0', fontFamily:'"Space Grotesk",sans-serif', lineHeight:1.05, fontSize:'clamp(1.9rem,3vw,3rem)' }}>
          {userFirstName ? `Welcome ${userFirstName}` : 'Welcome back'}
        </h2>
        <div className="hero-meta">
          <span>{longDate(today)}</span>
          <span>Next payday: {nextPayText}</span>
        </div>
        <div className="hero-action-row">
          <button type="button" className="hero-expense-button" onClick={onQuickAddExpense}>
            <span className="hero-expense-icon">+</span>
            <span>Quick Add Expense</span>
          </button>
        </div>
      </div>
      <div className="hero-panel hero-metrics-grid">
        <div className={`stat-chip${accountLeftAfterPrepaid < 0 ? ' is-negative' : ''}`}>
          <span>Left after pre-paid bills</span>
          <strong>{paycheckAmount ? fmt(accountLeftAfterPrepaid,false) : '-'}</strong>
        </div>
        <div className="stat-chip">
          <span>Due {periodLabel}</span>
          <strong>{period ? fmt(periodTotal,false) : '-'}</strong>
        </div>
        <div className="stat-chip"><span>Next bill payment</span><strong>{nextBillLabel}</strong></div>
        <div className="stat-chip"><span>Total debt</span><strong>{fmt(totalDebt,false)}</strong></div>
      </div>
    </div>
  );
}

