// ========== Flow (tabela diária) + AddModal + EditTxModal ==========
const { Avatar, Icon, TagPill, Currency, fmtBRL, fmtDateLong, isoToday, MONTH_NAMES_PT } = window.FinUtils;

const parseCents = (str) =>
  Math.round(parseFloat((str || '').replace(/\./g, '').replace(',', '.')) * 100) || 0;
const centsToStr = (cents) =>
  (cents / 100).toFixed(2).replace('.', ',');

// ========== DAILY BUDGET CARD ==========
function DailyBudgetCard({ state }) {
  const { user, txs, dailyBudgets } = state;
  const budget = (dailyBudgets || {})[String(user.id)];
  if (!budget?.amount || !budget?.startDate) return null;

  const today = new Date();
  const start = new Date(budget.startDate + 'T00:00:00');
  const monthsElapsed = (today.getFullYear() - start.getFullYear()) * 12 + (today.getMonth() - start.getMonth()) + 1;
  const totalBudget = budget.amount * Math.max(1, monthsElapsed);

  const totalSpent = txs
    .filter(t => t.userId === user.id && t.type === 'expense' && t.countsAgainstBudget !== false && t.date >= budget.startDate)
    .reduce((s, t) => s + t.amount, 0);
  const remaining = totalBudget - totalSpent;

  const currentMonth = today.toISOString().slice(0, 7);
  const thisMonthSpent = txs
    .filter(t => t.userId === user.id && t.type === 'expense' && t.countsAgainstBudget !== false && t.date.startsWith(currentMonth))
    .reduce((s, t) => s + t.amount, 0);
  const rollover = remaining - (budget.amount - thisMonthSpent);

  const usedPct  = Math.min(1, thisMonthSpent / budget.amount);
  const isOver   = remaining < 0;
  const barColor = isOver ? 'var(--expense)' : usedPct > 0.8 ? '#E8A94A' : 'var(--income)';

  return (
    <div className="card" style={{
      marginBottom: 'var(--s5)',
      background: isOver
        ? 'linear-gradient(135deg, oklch(0.97 0.03 15), oklch(0.99 0.01 15))'
        : 'linear-gradient(135deg, oklch(0.97 0.03 250), oklch(0.99 0.01 200))',
    }}>
      <div className="hstack" style={{ justifyContent: 'space-between', marginBottom: 6 }}>
        <div className="muted" style={{ fontSize: 12, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
          Orçamento do dia a dia · {MONTH_NAMES_PT[today.getMonth()]}
        </div>
        {rollover !== 0 && (
          <span style={{ fontSize: 11, fontWeight: 600, color: rollover > 0 ? 'var(--income)' : 'var(--expense)' }}>
            {rollover > 0 ? '+' : ''}{fmtBRL(rollover)} acumulado
          </span>
        )}
      </div>
      <div className="hstack" style={{ alignItems: 'baseline', gap: 10, marginBottom: 16 }}>
        <span style={{ fontSize: 36, fontWeight: 700, fontFamily: 'var(--f-display)', color: barColor }}>
          {fmtBRL(Math.abs(remaining))}
        </span>
        <span className="muted" style={{ fontSize: 14 }}>{remaining < 0 ? 'estourado' : 'disponível'}</span>
      </div>
      <div className="progress" style={{ height: 10, marginBottom: 10 }}>
        <div className="progress-fill" style={{ width: `${usedPct * 100}%`, background: barColor, transition: 'width 0.4s ease' }}/>
      </div>
      <div className="hstack" style={{ justifyContent: 'space-between', fontSize: 11, color: 'var(--text-mute)' }}>
        <span>Gasto este mês: {fmtBRL(thisMonthSpent)}</span>
        <span>Limite mensal: {fmtBRL(budget.amount)}</span>
      </div>
    </div>
  );
}

// ========== RECURRENCE PICKER ==========
const RECURRENCE_OPTIONS = [
  { id: null,       label: 'Sem repetição' },
  { id: 'weekly',   label: 'Semanal'       },
  { id: 'biweekly', label: 'Quinzenal'     },
  { id: 'monthly',  label: 'Mensal'        },
  { id: 'custom',   label: 'Personalizado' },
];

function RecurrencePicker({ value, onChange }) {
  const isCustom   = value && value.startsWith('custom:');
  const selected   = isCustom ? 'custom' : (value || null);
  const customDays = isCustom ? value.split(':')[1] : '';

  const handleChip = (id) => {
    if (id === 'custom') onChange('custom:7');
    else onChange(id);
  };

  return (
    <div className="field">
      <label>Recorrência</label>
      <div className="chip-select" style={{ width: '100%', flexWrap: 'wrap' }}>
        {RECURRENCE_OPTIONS.map(o => (
          <button key={String(o.id)} className={selected === o.id ? 'active' : ''}
                  onClick={() => handleChip(o.id)} style={{ flex: '1 1 auto' }}>
            {o.label}
          </button>
        ))}
      </div>
      {isCustom && (
        <div className="hstack" style={{ marginTop: 8, gap: 8, alignItems: 'center' }}>
          <span className="muted" style={{ fontSize: 12 }}>a cada</span>
          <input className="input" type="number" min="1" max="365" style={{ width: 72 }}
                 value={customDays}
                 onChange={e => onChange(`custom:${e.target.value}`)}/>
          <span className="muted" style={{ fontSize: 12 }}>dias</span>
        </div>
      )}
    </div>
  );
}

function recurrenceLabel(pattern) {
  if (!pattern) return null;
  if (pattern === 'weekly')   return 'Semanal';
  if (pattern === 'biweekly') return 'Quinzenal';
  if (pattern === 'monthly')  return 'Mensal';
  if (pattern.startsWith('custom:')) return `A cada ${pattern.split(':')[1]} dias`;
  return pattern;
}

const shiftMonth = (m, n) => {
  const [y, mo] = m.split('-').map(Number);
  const d = new Date(y, mo - 1 + n, 1);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
};

// ========== FLOW ==========
function Flow({ state, setState }) {
  const { user, txs, users, tags, goals, subs, savingsTarget } = state;
  const [filter, setFilter]             = React.useState('all');
  const [tagFilter, setTagFilter]       = React.useState(null);
  const [editingTx, setEditingTx]       = React.useState(null);
  const currentMonth                    = new Date().toISOString().slice(0, 7);
  const [selectedMonth, setSelectedMonth] = React.useState(currentMonth);

  // Running balance (all-time, for saldo column)
  const allSorted = [...txs.filter(t => t.userId === user.id || t.shared)].sort((a,b) => a.date < b.date ? -1 : 1);
  const runningByDay = {};
  let running = 0;
  allSorted.forEach(t => {
    running += t.type === 'income' ? t.amount : -t.amount;
    runningByDay[t.date] = running;
  });

  // Month-scoped base
  const monthBase = txs.filter(t => (t.userId === user.id || t.shared) && t.date.startsWith(selectedMonth));

  // Visible = month base + type/tag filters
  let visible = [...monthBase];
  if (filter === 'income')  visible = visible.filter(t => t.type === 'income');
  if (filter === 'expense') visible = visible.filter(t => t.type === 'expense');
  if (filter === 'saving')  visible = visible.filter(t => t.type === 'saving');
  if (filter === 'shared')  visible = visible.filter(t => t.shared);
  if (tagFilter)            visible = visible.filter(t => t.tags && t.tags.includes(tagFilter));
  visible = [...visible].sort((a, b) => (a.date < b.date ? 1 : -1));

  const groups = {};
  visible.forEach(t => { (groups[t.date] = groups[t.date] || []).push(t); });

  // KPIs from full month (no type filter)
  const income  = monthBase.filter(t => t.type === 'income').reduce((s,t) => s + t.amount, 0);
  const saving  = monthBase.filter(t => t.type === 'saving').reduce((s,t) => s + t.amount, 0);
  const expense = monthBase.filter(t => t.type !== 'income').reduce((s,t) => s + t.amount, 0);

  // Forecast (upcoming subs only relevant for current month)
  const isCurrentMonth = selectedMonth === currentMonth;
  const todayDay       = new Date().getDate();
  const upcomingSubs   = isCurrentMonth
    ? (subs || []).filter(s => s.active && (s.ownerId === user.id || s.shared) && s.day >= todayDay).reduce((t,s) => t + s.amount, 0)
    : 0;
  const forecastBalance = income - expense - upcomingSubs;

  // Saldo meta: savingsTarget − despesas avulsas do mês selecionado
  const nonRecurringExpenses = monthBase
    .filter(t => t.type === 'expense' && !t.recurrencePattern && !t.recurringParentId)
    .reduce((s,t) => s + t.amount, 0);
  const metaSaldo = (savingsTarget || 0) - nonRecurringExpenses;

  const selMonthParts = selectedMonth.split('-');
  const monthLabel = MONTH_NAMES_PT[+selMonthParts[1] - 1].toLowerCase() + ' de ' + selMonthParts[0];

  return (
    <div>
      <div className="page-head">
        <div>
          <div className="dim" style={{ fontSize: 12, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' }}>fluxo diário</div>
          <div className="hstack" style={{ gap: 12, alignItems: 'center', marginTop: 4 }}>
            <button onClick={() => setSelectedMonth(s => shiftMonth(s, -1))}
                    style={{ padding: '4px 10px', borderRadius: 8, border: '1px solid var(--border)', background: 'var(--surface)', cursor: 'pointer', fontSize: 16, lineHeight: 1 }}>‹</button>
            <h1 className="page-title" style={{ margin: 0 }}>{monthLabel.charAt(0).toUpperCase() + monthLabel.slice(1)}</h1>
            <button onClick={() => setSelectedMonth(s => shiftMonth(s, 1))}
                    style={{ padding: '4px 10px', borderRadius: 8, border: '1px solid var(--border)', background: 'var(--surface)', cursor: 'pointer', fontSize: 16, lineHeight: 1 }}>›</button>
            {!isCurrentMonth && (
              <button onClick={() => setSelectedMonth(currentMonth)}
                      style={{ fontSize: 11, color: 'var(--accent)', fontWeight: 600, padding: '2px 8px', border: '1px solid var(--accent)', borderRadius: 6, cursor: 'pointer', background: 'transparent' }}>
                hoje
              </button>
            )}
          </div>
          <div className="page-subtitle" style={{ marginTop: 4 }}>{visible.length} transações · saldo acumulado <strong className="num" style={{ color: 'var(--text)' }}>{fmtBRL(running)}</strong></div>
        </div>
        <div className="page-actions">
          <div className="chip-select">
            <button className={filter === 'all'     ? 'active' : ''} onClick={() => setFilter('all')}>Tudo</button>
            <button className={filter === 'income'  ? 'active' : ''} onClick={() => setFilter('income')}>Entradas</button>
            <button className={filter === 'expense' ? 'active' : ''} onClick={() => setFilter('expense')}>Saídas</button>
            <button className={filter === 'saving'  ? 'active' : ''} onClick={() => setFilter('saving')}>Investido</button>
            <button className={filter === 'shared'  ? 'active' : ''} onClick={() => setFilter('shared')}>Compart.</button>
          </div>
          <button className="btn btn-primary" onClick={() => setState(s => ({ ...s, showAdd: true }))}>
            <Icon name="plus" size={14}/> Nova
          </button>
        </div>
      </div>

      {isCurrentMonth && <DailyBudgetCard state={state} />}

      <div className="kpi-grid" style={{ gridTemplateColumns: 'repeat(5, 1fr)' }}>
        <div className="kpi">
          <div className="kpi-label"><span className="kpi-dot" style={{ background: 'var(--income)' }}/> Entradas</div>
          <div className="kpi-value"><Currency cents={income} /></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span className="kpi-dot" style={{ background: 'var(--expense)' }}/> Saídas</div>
          <div className="kpi-value"><Currency cents={expense} /></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span className="kpi-dot" style={{ background: 'var(--accent)' }}/> Economizado</div>
          <div className="kpi-value"><Currency cents={saving} /></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span className="kpi-dot" style={{ background: 'var(--text-mute)' }}/> {isCurrentMonth ? 'Previsão fechamento' : 'Saldo do mês'}</div>
          <div className="kpi-value" style={{ color: forecastBalance < 0 ? 'var(--expense)' : undefined }}><Currency cents={forecastBalance} /></div>
          {upcomingSubs > 0 && <div className="kpi-meta"><span className="muted">{fmtBRL(upcomingSubs)} a vencer</span></div>}
        </div>
        {savingsTarget > 0 && (
          <div className="kpi">
            <div className="kpi-label"><span className="kpi-dot" style={{ background: 'var(--c-mercado)' }}/> Saldo meta</div>
            <div className="kpi-value" style={{ color: metaSaldo < 0 ? 'var(--expense)' : 'var(--income)' }}><Currency cents={metaSaldo} /></div>
            <div className="kpi-meta"><span className="muted">{fmtBRL(nonRecurringExpenses)} gastos avulsos</span></div>
          </div>
        )}
      </div>

      <div className="hstack" style={{ flexWrap: 'wrap', marginBottom: 'var(--s4)', gap: 8 }}>
        <span className="muted" style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginRight: 4 }}>Categoria:</span>
        <button className="tag-option" style={{ opacity: tagFilter ? 0.6 : 1 }} onClick={() => setTagFilter(null)}>Todas</button>
        {tags.slice(0, 9).map(t => (
          <button key={t.id} className={`tag-option ${tagFilter === t.id ? 'selected' : ''}`}
                  onClick={() => setTagFilter(tagFilter === t.id ? null : t.id)}
                  style={{ color: tagFilter === t.id ? t.color : 'var(--text-dim)' }}>
            <span>{t.icon}</span> {t.name}
          </button>
        ))}
      </div>

      <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
        {visible.length === 0 ? (
          <div style={{ textAlign: 'center', padding: '48px 24px', color: 'var(--text-mute)' }}>
            <div style={{ fontSize: 32, marginBottom: 12 }}>💸</div>
            <div style={{ fontWeight: 500 }}>Nenhuma transação</div>
            <div style={{ fontSize: 12, marginTop: 4 }}>Adicione sua primeira transação acima.</div>
          </div>
        ) : (
          <table className="tx-table">
            <thead>
              <tr>
                <th style={{ width: 22 }}></th>
                <th>Descrição</th>
                <th className="col-tags">Categoria</th>
                <th>Dono</th>
                <th style={{ textAlign: 'right' }}>Valor</th>
                <th className="col-date" style={{ textAlign: 'right' }}>Saldo</th>
                <th style={{ width: 64 }}></th>
              </tr>
            </thead>
            <tbody>
              {Object.entries(groups).sort((a,b) => a[0] < b[0] ? 1 : -1).map(([date, ts]) => {
                const dayTotal = ts.reduce((s,t) => s + (t.type === 'income' ? t.amount : -t.amount), 0);
                return (
                  <React.Fragment key={date}>
                    <tr className="day-header">
                      <td colSpan={4}>{fmtDateLong(date)}</td>
                      <td style={{ textAlign: 'right', color: dayTotal >= 0 ? 'var(--income)' : 'var(--expense)' }}>
                        {dayTotal >= 0 ? '+' : '−'} {fmtBRL(Math.abs(dayTotal), { noPrefix: true })}
                      </td>
                      <td className="col-date balance-cell">{fmtBRL(runningByDay[date] || 0)}</td>
                      <td></td>
                    </tr>
                    {ts.map(t => (
                      <TxRow key={t.id} tx={t} tags={tags} users={users} goals={goals} currentUser={user}
                             running={runningByDay[t.date] || 0}
                             onEdit={() => setEditingTx(t)} />
                    ))}
                  </React.Fragment>
                );
              })}
            </tbody>
          </table>
        )}
      </div>

      {editingTx && (
        <EditTxModal tx={editingTx} state={state} setState={setState} onClose={() => setEditingTx(null)} />
      )}
    </div>
  );
}

function TxRow({ tx, tags, users, goals, currentUser, running, onEdit }) {
  const owner  = users.find(u => u.id === tx.userId);
  const other  = users.find(u => u.id !== tx.userId);
  const isMine = tx.userId === currentUser.id;
  const txTags = (tx.tags || []).map(tid => tags.find(t => t.id === tid)).filter(Boolean);
  const goal   = tx.type === 'saving' && tx.goalId ? goals.find(g => g.id == tx.goalId) : null;

  const typeColor = tx.type === 'income' ? 'var(--income)' : tx.type === 'saving' ? 'var(--accent)' : 'var(--expense)';
  const amountPrefix = tx.type === 'income' ? '+ ' : '− ';

  return (
    <tr style={ tx.type === 'saving' ? { background: 'oklch(0.98 0.01 250)' } : {} }>
      <td>
        <div style={{ width: 8, height: 8, borderRadius: 2, background: typeColor, opacity: 0.85 }}/>
      </td>
      <td>
        <div style={{ fontWeight: 500 }}>{tx.description}</div>
        {goal && (
          <div style={{ fontSize: 10, color: 'var(--accent)', marginTop: 1 }}>→ {goal.icon} {goal.name}</div>
        )}
        {tx.type === 'expense' && tx.countsAgainstBudget === false && (
          <div style={{ fontSize: 10, color: 'var(--text-mute)', marginTop: 1 }}>fora do orçamento</div>
        )}
        {tx.recurrencePattern && (
          <div style={{ fontSize: 10, color: 'var(--text-mute)', marginTop: 1 }}>↻ {recurrenceLabel(tx.recurrencePattern)}</div>
        )}
        {tx.recurringParentId && !tx.recurrencePattern && (
          <div style={{ fontSize: 10, color: 'var(--text-mute)', marginTop: 1 }}>↻ gerado automaticamente</div>
        )}
      </td>
      <td className="col-tags">
        <div className="hstack" style={{ gap: 4, flexWrap: 'wrap' }}>
          {tx.type === 'saving' && !txTags.length
            ? <span style={{ fontSize: 11, color: 'var(--accent)', fontWeight: 500 }}>Investimento</span>
            : txTags.length === 0
              ? <span className="muted" style={{ fontSize: 11 }}>—</span>
              : txTags.map(t => <TagPill key={t.id} tag={t} />)
          }
        </div>
      </td>
      <td>
        {tx.shared ? (
          <span className="shared-mark">
            <span className="avatars">
              {owner && <Avatar user={owner} size="xs" />}
              {other && <Avatar user={other} size="xs" />}
            </span>
            {isMine ? 'compartilhada' : (owner ? owner.name : '?')}
          </span>
        ) : (
          <span className="hstack" style={{ gap: 6 }}>
            {owner && <Avatar user={owner} size="xs" />}
            <span style={{ fontSize: 11, color: 'var(--text-mute)' }}>{owner ? owner.name : '?'}</span>
          </span>
        )}
      </td>
      <td style={{ textAlign: 'right', fontWeight: 600, color: typeColor, fontFamily: 'var(--f-display)', fontSize: 15 }}>
        {amountPrefix}{fmtBRL(tx.amount, { noPrefix: true })}
      </td>
      <td className="col-date balance-cell">{fmtBRL(running)}</td>
      <td>
        {isMine && (
          <button title="Editar" onClick={onEdit}
                  style={{ padding: 4, borderRadius: 6, color: 'var(--text-mute)', display: 'flex', alignItems: 'center' }}>
            <Icon name="edit" size={14}/>
          </button>
        )}
      </td>
    </tr>
  );
}

// ========== EDIT TX MODAL ==========
function EditTxModal({ tx, state, setState, onClose }) {
  const { tags, users, goals, user } = state;
  const [type,                setType]                = React.useState(tx.type);
  const [amount,              setAmount]              = React.useState(centsToStr(tx.amount));
  const [desc,                setDesc]                = React.useState(tx.description);
  const [date,                setDate]                = React.useState(tx.date);
  const [selectedTags,        setSelectedTags]        = React.useState(tx.tags || []);
  const [shared,              setShared]              = React.useState(tx.shared || false);
  const [countsAgainstBudget, setCountsAgainstBudget] = React.useState(tx.countsAgainstBudget !== false);
  const [goalId,              setGoalId]              = React.useState(tx.goalId || null);
  const [recurrencePattern,   setRecurrencePattern]   = React.useState(tx.recurrencePattern || null);
  const [saving,              setSaving]              = React.useState(false);

  const parsedAmount = parseCents(amount);
  const otherUser    = users.find(u => u.id !== user.id);
  const isSaving     = type === 'saving';

  const save = () => {
    if (!parsedAmount || !desc || saving) return;
    if (isSaving && !goalId) return;
    setSaving(true);
    fetch(`/api/transactions/${tx.id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        userId: user.id, type, amount: parsedAmount, description: desc, date,
        tags: selectedTags, shared,
        countsAgainstBudget: isSaving ? false : countsAgainstBudget,
        goalId: isSaving ? goalId : null,
        recurrencePattern,
      }),
    })
      .then(r => r.json())
      .then(saved => {
        setState(s => {
          const txs   = s.txs.map(t => t.id === tx.id ? saved : t);
          const goals = saved.goalId
            ? s.goals.map(g => g.id == saved.goalId ? { ...g, current: g.current } : g)
            : s.goals;
          return { ...s, txs, goals };
        });
        // Reload goals to reflect goal deposit changes
        fetch('/api/data').then(r => r.json()).then(data => setState(s => ({ ...s, goals: data.goals })));
        onClose();
      })
      .catch(() => setSaving(false));
  };

  const del = () => {
    if (!window.confirm('Excluir esta transação?')) return;
    fetch(`/api/transactions/${tx.id}?userId=${user.id}`, { method: 'DELETE' })
      .then(() => {
        setState(s => ({ ...s, txs: s.txs.filter(t => t.id !== tx.id) }));
        if (tx.type === 'saving') {
          fetch('/api/data').then(r => r.json()).then(data => setState(s => ({ ...s, goals: data.goals })));
        }
        onClose();
      });
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="hstack" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
          <h2 className="display" style={{ fontSize: 28, margin: 0 }}>Editar transação</h2>
          <button onClick={onClose} style={{ padding: 8, borderRadius: 8, color: 'var(--text-mute)' }}><Icon name="x" size={18}/></button>
        </div>

        <div className="segmented" style={{ marginBottom: 20 }}>
          <button className={type === 'income'  ? 'active-income'  : ''} onClick={() => setType('income')}>
            <Icon name="arrowUp" size={14}/> Entrada
          </button>
          <button className={type === 'expense' ? 'active-expense' : ''} onClick={() => setType('expense')}>
            <Icon name="arrowDown" size={14}/> Saída
          </button>
          <button className={type === 'saving'  ? 'active' : ''} onClick={() => setType('saving')}
                  style={type === 'saving' ? { background: 'var(--accent)', color: 'white', borderColor: 'var(--accent)' } : {}}>
            💰 Investimento
          </button>
        </div>

        <div className="field">
          <label>Valor</label>
          <div className="hstack" style={{ alignItems: 'baseline', gap: 8 }}>
            <span className="display" style={{ fontSize: 24, color: 'var(--text-mute)' }}>R$</span>
            <input className="input-lg" type="text" inputMode="decimal" placeholder="0,00"
                   value={amount} onChange={e => setAmount(e.target.value)} autoFocus style={{ flex: 1 }}/>
          </div>
        </div>

        <div className="field">
          <label>Descrição</label>
          <input className="input" placeholder="Ex: mercado, aluguel, salário..." value={desc} onChange={e => setDesc(e.target.value)}/>
        </div>

        <div className="field">
          <label>Data</label>
          <input className="input" type="date" value={date} onChange={e => setDate(e.target.value)}/>
        </div>

        {isSaving ? (
          <div className="field">
            <label>Meta de destino <span style={{ color: 'var(--expense)' }}>*</span></label>
            <div className="vstack" style={{ gap: 8 }}>
              {(goals || []).map(g => (
                <button key={g.id}
                  onClick={() => setGoalId(g.id)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', borderRadius: 10,
                    border: `2px solid ${goalId == g.id ? g.color : 'var(--border)'}`,
                    background: goalId == g.id ? `color-mix(in oklch, ${g.color} 10%, white)` : 'var(--bg-sunken)',
                    cursor: 'pointer', textAlign: 'left',
                  }}>
                  <span style={{ fontSize: 20 }}>{g.icon}</span>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{g.name}</div>
                    <div style={{ fontSize: 11, color: 'var(--text-mute)' }}>{fmtBRL(g.current)} / {fmtBRL(g.target)}</div>
                  </div>
                  {goalId == g.id && <Icon name="check" size={14} style={{ color: g.color }}/>}
                </button>
              ))}
              {(!goals || goals.length === 0) && (
                <p className="muted" style={{ fontSize: 12 }}>Nenhuma meta cadastrada. Crie uma meta primeiro.</p>
              )}
            </div>
          </div>
        ) : (
          type === 'expense' && (
            <div className="field">
              <label>Categorias</label>
              <div className="tag-picker">
                {tags.map(t => (
                  <button key={t.id}
                    className={`tag-option ${selectedTags.includes(t.id) ? 'selected' : ''}`}
                    style={{ color: selectedTags.includes(t.id) ? t.color : undefined }}
                    onClick={() => setSelectedTags(s => s.includes(t.id) ? s.filter(i => i !== t.id) : [...s, t.id])}>
                    <span>{t.icon}</span> {t.name}
                  </button>
                ))}
              </div>
            </div>
          )
        )}

        {!isSaving && (
          <div className="toggle-row">
            <div>
              <div style={{ fontWeight: 500, fontSize: 13 }}>Compartilhada com {otherUser ? otherUser.name : 'outro usuário'}</div>
              <div className="muted" style={{ fontSize: 11 }}>Aparece para os dois · só você edita.</div>
            </div>
            <button className={`toggle ${shared ? 'on' : ''}`} onClick={() => setShared(!shared)} />
          </div>
        )}

        {type === 'expense' && (
          <div className="toggle-row" style={{ borderBottom: '1px solid var(--border)', marginBottom: 20 }}>
            <div>
              <div style={{ fontWeight: 500, fontSize: 13 }}>Conta no orçamento diário</div>
              <div className="muted" style={{ fontSize: 11 }}>Desative para aluguel, contas fixas.</div>
            </div>
            <button className={`toggle ${countsAgainstBudget ? 'on' : ''}`} onClick={() => setCountsAgainstBudget(!countsAgainstBudget)} />
          </div>
        )}

        <RecurrencePicker value={recurrencePattern} onChange={setRecurrencePattern} />

        <div className="hstack" style={{ justifyContent: 'space-between', marginTop: 20 }}>
          <button className="btn" style={{ color: 'var(--expense)', borderColor: 'var(--expense)' }} onClick={del}>
            <Icon name="trash" size={14}/> Excluir
          </button>
          <div className="hstack" style={{ gap: 10 }}>
            <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
            <button className="btn btn-primary btn-lg" onClick={save}
                    disabled={!parsedAmount || !desc || saving || (isSaving && !goalId)}>
              <Icon name="check" size={14}/> Salvar
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ========== ADD MODAL ==========
function AddModal({ state, setState, onClose }) {
  const { tags, users, goals, user } = state;
  const [type,                setType]                = React.useState('expense');
  const [amount,              setAmount]              = React.useState('');
  const [desc,                setDesc]                = React.useState('');
  const [date,                setDate]                = React.useState(isoToday());
  const [selectedTags,        setSelectedTags]        = React.useState([]);
  const [shared,              setShared]              = React.useState(false);
  const [countsAgainstBudget, setCountsAgainstBudget] = React.useState(true);
  const [goalId,              setGoalId]              = React.useState(null);
  const [recurrencePattern,   setRecurrencePattern]   = React.useState(null);
  const [saving,              setSaving]              = React.useState(false);

  const parsedAmount = parseCents(amount);
  const otherUser    = users.find(u => u.id !== user.id);
  const isSaving     = type === 'saving';

  const save = () => {
    if (!parsedAmount || !desc || saving) return;
    if (isSaving && !goalId) return;
    const newTx = {
      userId: user.id, type, amount: parsedAmount, description: desc, date,
      tags: isSaving ? [] : selectedTags,
      shared: isSaving ? false : shared,
      countsAgainstBudget: isSaving ? false : countsAgainstBudget,
      goalId: isSaving ? goalId : null,
      recurrencePattern,
    };
    const tempId = Date.now();
    setState(s => ({ ...s, txs: [...s.txs, { ...newTx, id: tempId }], showAdd: false }));
    setSaving(true);

    fetch('/api/transactions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(newTx),
    })
      .then(r => r.json())
      .then(saved => {
        setState(s => ({ ...s, txs: s.txs.map(t => t.id === tempId ? saved : t) }));
        if (isSaving) {
          fetch('/api/data').then(r => r.json()).then(data => setState(s => ({ ...s, goals: data.goals })));
        }
      })
      .catch(() => {});
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="hstack" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
          <h2 className="display" style={{ fontSize: 28, margin: 0 }}>Nova transação</h2>
          <button onClick={onClose} style={{ padding: 8, borderRadius: 8, color: 'var(--text-mute)' }}><Icon name="x" size={18}/></button>
        </div>

        <div className="segmented" style={{ marginBottom: 20 }}>
          <button className={type === 'income'  ? 'active-income'  : ''} onClick={() => setType('income')}>
            <Icon name="arrowUp" size={14}/> Entrada
          </button>
          <button className={type === 'expense' ? 'active-expense' : ''} onClick={() => setType('expense')}>
            <Icon name="arrowDown" size={14}/> Saída
          </button>
          <button className={type === 'saving'  ? 'active' : ''} onClick={() => setType('saving')}
                  style={type === 'saving' ? { background: 'var(--accent)', color: 'white', borderColor: 'var(--accent)' } : {}}>
            💰 Investimento
          </button>
        </div>

        <div className="field">
          <label>Valor</label>
          <div className="hstack" style={{ alignItems: 'baseline', gap: 8 }}>
            <span className="display" style={{ fontSize: 24, color: 'var(--text-mute)' }}>R$</span>
            <input className="input-lg" type="text" inputMode="decimal" placeholder="0,00"
                   value={amount} onChange={e => setAmount(e.target.value)} autoFocus style={{ flex: 1 }}/>
          </div>
        </div>

        <div className="field">
          <label>Descrição</label>
          <input className="input" placeholder="Ex: mercado, aluguel, salário..." value={desc} onChange={e => setDesc(e.target.value)}/>
        </div>

        <div className="field">
          <label>Data</label>
          <input className="input" type="date" value={date} onChange={e => setDate(e.target.value)}/>
        </div>

        {isSaving ? (
          <div className="field">
            <label>Meta de destino <span style={{ color: 'var(--expense)' }}>*</span></label>
            <div className="vstack" style={{ gap: 8 }}>
              {(goals || []).map(g => (
                <button key={g.id}
                  onClick={() => setGoalId(g.id)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', borderRadius: 10,
                    border: `2px solid ${goalId == g.id ? g.color : 'var(--border)'}`,
                    background: goalId == g.id ? `color-mix(in oklch, ${g.color} 10%, white)` : 'var(--bg-sunken)',
                    cursor: 'pointer', textAlign: 'left',
                  }}>
                  <span style={{ fontSize: 20 }}>{g.icon}</span>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{g.name}</div>
                    <div style={{ fontSize: 11, color: 'var(--text-mute)' }}>{fmtBRL(g.current)} / {fmtBRL(g.target)}</div>
                  </div>
                  {goalId == g.id && <Icon name="check" size={14}/>}
                </button>
              ))}
              {(!goals || goals.length === 0) && (
                <p className="muted" style={{ fontSize: 12 }}>Nenhuma meta cadastrada. Crie uma meta primeiro.</p>
              )}
            </div>
          </div>
        ) : (
          type === 'expense' && (
            <div className="field">
              <label>Categorias</label>
              <div className="tag-picker">
                {tags.map(t => (
                  <button key={t.id}
                    className={`tag-option ${selectedTags.includes(t.id) ? 'selected' : ''}`}
                    style={{ color: selectedTags.includes(t.id) ? t.color : undefined }}
                    onClick={() => setSelectedTags(s => s.includes(t.id) ? s.filter(i => i !== t.id) : [...s, t.id])}>
                    <span>{t.icon}</span> {t.name}
                  </button>
                ))}
              </div>
            </div>
          )
        )}

        {!isSaving && (
          <div className="toggle-row">
            <div>
              <div style={{ fontWeight: 500, fontSize: 13 }}>Compartilhada com {otherUser ? otherUser.name : 'outro usuário'}</div>
              <div className="muted" style={{ fontSize: 11 }}>Aparece para os dois · só você edita.</div>
            </div>
            <button className={`toggle ${shared ? 'on' : ''}`} onClick={() => setShared(!shared)} />
          </div>
        )}

        {type === 'expense' && (
          <div className="toggle-row">
            <div>
              <div style={{ fontWeight: 500, fontSize: 13 }}>Conta no orçamento diário</div>
              <div className="muted" style={{ fontSize: 11 }}>Desative para aluguel, contas fixas.</div>
            </div>
            <button className={`toggle ${countsAgainstBudget ? 'on' : ''}`} onClick={() => setCountsAgainstBudget(!countsAgainstBudget)} />
          </div>
        )}

        <RecurrencePicker value={recurrencePattern} onChange={setRecurrencePattern} />

        <div className="hstack" style={{ justifyContent: 'flex-end', gap: 10, marginTop: 12 }}>
          <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary btn-lg" onClick={save}
                  disabled={!parsedAmount || !desc || saving || (isSaving && !goalId)}>
            <Icon name="check" size={14}/>
            {isSaving ? 'Investir' : type === 'income' ? 'Adicionar entrada' : 'Adicionar saída'}
          </button>
        </div>
      </div>
    </div>
  );
}

window.Flow     = Flow;
window.AddModal = AddModal;
