// Budget page — pre-loaded estimates from BUDGET data + user-added expenses + manual actuals.
// Storage:
//   roadtrip-budget-v1        — actuals keyed by line-item id (number)
//   roadtrip-budget-custom-v1 — user-added line items: [{id, category, label, dayN, est}]

const BUDGET_STORAGE_KEY  = 'roadtrip-budget-v1';
const CUSTOM_BUDGET_KEY   = 'roadtrip-budget-custom-v1';

function useBudgetActuals() {
  const [data, setData] = React.useState(() => {
    try {
      const raw = localStorage.getItem(BUDGET_STORAGE_KEY);
      return raw ? JSON.parse(raw) : {};
    } catch { return {}; }
  });
  const setActual = React.useCallback((id, value) => {
    setData(prev => {
      const next = { ...prev };
      if (value === '' || value == null) {
        delete next[id];
      } else {
        next[id] = Number(value);
      }
      try { localStorage.setItem(BUDGET_STORAGE_KEY, JSON.stringify(next)); } catch {}
      return next;
    });
  }, []);
  return [data, setActual];
}

function useCustomItems() {
  const [items, setItems] = React.useState(() => {
    try {
      const raw = localStorage.getItem(CUSTOM_BUDGET_KEY);
      return raw ? JSON.parse(raw) : [];
    } catch { return []; }
  });
  const persist = (next) => {
    try { localStorage.setItem(CUSTOM_BUDGET_KEY, JSON.stringify(next)); } catch {}
    setItems(next);
  };
  const addItem = (it) => persist([...items, it]);
  const removeItem = (id) => persist(items.filter(i => i.id !== id));
  return [items, addItem, removeItem];
}

function fmt(n) {
  if (n == null || isNaN(n)) return '—';
  return '$' + Math.round(n).toLocaleString();
}

function CategoryRow({ cat, items, actuals, onActual, onDelete, defaultOpen }) {
  const [open, setOpen] = React.useState(!!defaultOpen);
  const est = items.reduce((s, i) => s + (i.est || 0), 0);
  const spent = items.reduce((s, i) => s + (actuals[i.id] || 0), 0);
  const pct = est > 0 ? Math.min((spent / est) * 100, 100) : 0;
  const over = spent > est;

  return (
    <div className={`cat-row ${open ? 'open' : ''}`}>
      <div className="cat-row-head" onClick={() => setOpen(!open)}>
        <div className="cat-row-top">
          <div className="cat-row-name">
            <span className="cat-dot" style={{ background: cat.color }} />
            <span className="name">{cat.label}</span>
            <span className="count">{items.length}</span>
          </div>
          <div className="cat-row-stats">
            <div className="spent">{fmt(spent)}</div>
            <div className="est">of {fmt(est)} est.</div>
          </div>
        </div>
        <div className={`cat-bar ${over ? 'over' : ''}`}>
          <div
            className="cat-bar-fill"
            style={{ width: `${pct}%`, background: cat.color }}
          />
        </div>
      </div>

      {open && (
        <div className="line-items">
          {items.length === 0 && (
            <div style={{
              padding: '12px 0', fontSize: '12px',
              color: 'var(--ink-muted)', fontStyle: 'italic'
            }}>
              No items yet. Add one with the button below.
            </div>
          )}
          {items.map(item => (
            <div className={`line-item ${item.custom ? 'custom' : ''}`} key={item.id}>
              <div>
                <div className="li-label">
                  {item.label}
                  {item.custom && (
                    <button
                      className="li-del"
                      onClick={() => onDelete(item.id)}
                      title="Delete"
                      aria-label="Delete"
                    >×</button>
                  )}
                </div>
                {item.dayN && <div className="li-day">Day {item.dayN}</div>}
              </div>
              <div className="li-actual-wrap">
                <span className="dollar">$</span>
                <input
                  className="li-actual"
                  type="number"
                  inputMode="decimal"
                  placeholder={String(item.est)}
                  value={actuals[item.id] != null ? actuals[item.id] : ''}
                  onChange={e => onActual(item.id, e.target.value)}
                />
              </div>
              <div className="li-est">est. {fmt(item.est)}</div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function AddExpenseForm({ categories, defaultCategory, onCancel, onSubmit }) {
  const [label, setLabel] = React.useState('');
  const [est, setEst] = React.useState('');
  const [category, setCategory] = React.useState(defaultCategory || categories[0].id);
  const [dayN, setDayN] = React.useState('');

  const submit = (e) => {
    e.preventDefault();
    if (!label.trim()) return;
    onSubmit({
      id: 'custom-' + Date.now() + '-' + Math.random().toString(36).slice(2, 6),
      category,
      label: label.trim(),
      dayN: dayN ? Number(dayN) : null,
      est: Number(est) || 0,
      custom: true,
    });
  };

  return (
    <form className="budget-add-form" onSubmit={submit}>
      <div className="bf-row">
        <label>Description</label>
        <input
          type="text"
          autoFocus
          value={label}
          onChange={e => setLabel(e.target.value)}
          placeholder="e.g. Surf lesson · Half Moon Bay"
        />
      </div>
      <div className="bf-grid">
        <div className="bf-row">
          <label>Category</label>
          <select value={category} onChange={e => setCategory(e.target.value)}>
            {categories.map(c => <option key={c.id} value={c.id}>{c.label}</option>)}
          </select>
        </div>
        <div className="bf-row">
          <label>Estimate ($)</label>
          <input
            type="number"
            inputMode="decimal"
            value={est}
            onChange={e => setEst(e.target.value)}
            placeholder="0"
          />
        </div>
      </div>
      <div className="bf-row">
        <label>Day (optional, 1–7)</label>
        <input
          type="number"
          min="1"
          max="7"
          value={dayN}
          onChange={e => setDayN(e.target.value)}
          placeholder="leave blank if not day-specific"
        />
      </div>
      <div className="aof-actions">
        <button type="button" className="aof-btn" onClick={onCancel}>Cancel</button>
        <button type="submit" className="aof-btn primary">Add</button>
      </div>
    </form>
  );
}

function BudgetPage() {
  const [actuals, setActual] = useBudgetActuals();
  const [customs, addCustom, removeCustom] = useCustomItems();
  const [adding, setAdding] = React.useState(false);
  const BUDGET = window.BUDGET;

  const allItems = React.useMemo(() => [...BUDGET.items, ...customs], [customs]);

  // Group items by category
  const byCat = React.useMemo(() => {
    const map = {};
    BUDGET.categories.forEach(c => { map[c.id] = []; });
    allItems.forEach(it => {
      if (!map[it.category]) map[it.category] = [];
      map[it.category].push(it);
    });
    return map;
  }, [allItems]);

  const totalEst = allItems.reduce((s, i) => s + (i.est || 0), 0);
  const totalSpent = allItems.reduce((s, i) => s + (actuals[i.id] || 0), 0);
  const remaining = totalEst - totalSpent;
  const pct = totalEst > 0 ? Math.min((totalSpent / totalEst) * 100, 100) : 0;
  const loggedCount = Object.keys(actuals).length;

  return (
    <>
      {window.PageHeader && <window.PageHeader title="Budget Tracker" />}
      <section id="budget" data-screen-label="Budget">
      <div className="page-head no-safe">
        <h1 className="ph-title">Where the money goes</h1>
        <p className="ph-sub">Estimates pulled from your confirmation emails. Add your own line items, log actuals as you go.</p>
      </div>

      <div className="budget-summary">
        <div className="bs-eyebrow">Trip Total</div>
        <div className="bs-totals">
          <span className="bs-spent">{fmt(totalSpent)}</span>
          <span className="bs-of">of {fmt(totalEst)} estimated</span>
        </div>
        <div className="bs-bar">
          <div className="bs-bar-fill" style={{ width: `${pct}%` }} />
        </div>
        <div className="bs-meta">
          <span>{loggedCount} of {allItems.length} items logged</span>
          <span style={{ color: remaining < 0 ? '#ffd1c2' : 'inherit' }}>
            {remaining >= 0 ? `${fmt(remaining)} remaining` : `${fmt(-remaining)} over`}
          </span>
        </div>
      </div>

      <div className="page-body">
        <div className="cat-list">
          {BUDGET.categories.map((cat) => (
            <CategoryRow
              key={cat.id}
              cat={cat}
              items={byCat[cat.id] || []}
              actuals={actuals}
              onActual={setActual}
              onDelete={removeCustom}
              defaultOpen={false}
            />
          ))}
        </div>

        <div className="budget-add-row">
          {!adding && (
            <button className="budget-add-btn" onClick={() => setAdding(true)}>
              + Add expense
            </button>
          )}
        </div>
        {adding && (
          <AddExpenseForm
            categories={BUDGET.categories}
            onCancel={() => setAdding(false)}
            onSubmit={(item) => {
              addCustom(item);
              setAdding(false);
            }}
          />
        )}
      </div>
    </section>
    </>
  );
}

window.BudgetPage = BudgetPage;
