// Activity — overview (forecast + last 5 tx) with separate sub-views for full
// transaction history and budgeting.

const DURATIONS = [
  { key: "week", label: "This week" },
  { key: "month", label: "This month" },
  { key: "quarter", label: "Quarter" },
  { key: "year", label: "This year" },
  { key: "all", label: "All time" },
];

const EDITABLE_CATS = [
  "Food",
  "Transport",
  "Shopping",
  "Bills",
  "Transfers",
  "Income",
  "Investments",
];

function TransactionsScreen({ theme, accent, onAskHimma, onOpenPaywall }) {
  const [view, setView] = React.useState("overview"); // 'overview' | 'list' | 'budget'

  // tx state — shared across views
  const [txs, setTxs] = React.useState(TRANSACTIONS.map((t) => ({ ...t })));
  const [editing, setEditing] = React.useState(null);
  const [recatId, setRecatId] = React.useState(null);
  const [confirmDelete, setConfirmDelete] = React.useState(null);

  // budget state — used in budget view
  const [budgets, setBudgets] = React.useState(BUDGETS);
  const [editingBudget, setEditingBudget] = React.useState(false);

  const updateCategory = (id, newCat) => {
    setTxs((all) =>
      all.map((t) => (t.id === id ? { ...t, category: newCat } : t)),
    );
    setRecatId(null);
    setEditing(null);
  };
  const deleteTx = (id) => {
    setTxs((all) => all.filter((t) => t.id !== id));
    setEditing(null);
    setConfirmDelete(null);
  };

  const editingTx = editing ? txs.find((t) => t.id === editing) : null;
  const recatTx = recatId ? txs.find((t) => t.id === recatId) : null;
  const deleteTxRecord = confirmDelete
    ? txs.find((t) => t.id === confirmDelete)
    : null;

  const headerTitle =
    view === "list"
      ? "Transactions"
      : view === "budget"
        ? "Budget"
        : "Activity";
  const headerSubtitle =
    view === "list"
      ? "All accounts"
      : view === "budget"
        ? `${TODAY.monthName} ${TODAY.year}`
        : `${TODAY.monthName} ${TODAY.year}`;

  const headerAction =
    view === "overview" ? (
      <button
        onClick={() => setView("budget")}
        style={{
          background: theme.surface,
          border: `0.5px solid ${theme.line2}`,
          borderRadius: 999,
          padding: "7px 12px",
          color: theme.text,
          fontFamily: FONTS.ui,
          fontSize: 11.5,
          fontWeight: 500,
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          gap: 6,
          whiteSpace: "nowrap",
        }}
      >
        <Ico.target size={12} /> Budget
      </button>
    ) : (
      <button
        onClick={() => setView("overview")}
        style={{
          background: "transparent",
          border: "none",
          color: theme.textDim,
          fontFamily: FONTS.ui,
          fontSize: 12,
          fontWeight: 500,
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          gap: 4,
        }}
      >
        <Ico.chevL size={13} /> Activity
      </button>
    );

  return (
    <Screen theme={theme}>
      <ScreenHeader
        title={headerTitle}
        subtitle={headerSubtitle}
        theme={theme}
        accent={accent}
        action={headerAction}
      />

      {view === "overview" && (
        <OverviewBody
          theme={theme}
          accent={accent}
          txs={txs}
          budgets={budgets}
          onTxClick={(id) => setEditing(id)}
          onSeeAll={() => setView("list")}
          onAskHimma={onAskHimma}
          onOpenPaywall={onOpenPaywall}
        />
      )}
      {view === "list" && (
        <AllBody
          theme={theme}
          accent={accent}
          txs={txs}
          onTxClick={(id) => setEditing(id)}
        />
      )}
      {view === "budget" && (
        <BudgetBody
          theme={theme}
          accent={accent}
          txs={txs}
          budgets={budgets}
          onEditBudget={() => setEditingBudget(true)}
        />
      )}

      {editingTx && !recatTx && !deleteTxRecord && (
        <TxActionsSheet
          tx={editingTx}
          theme={theme}
          accent={accent}
          onClose={() => setEditing(null)}
          onReCategorize={() => setRecatId(editingTx.id)}
          onDelete={() => setConfirmDelete(editingTx.id)}
        />
      )}
      {recatTx && (
        <CategoryPicker
          tx={recatTx}
          theme={theme}
          accent={accent}
          onClose={() => setRecatId(null)}
          onPick={(c) => updateCategory(recatTx.id, c)}
        />
      )}
      {deleteTxRecord && (
        <DeleteConfirmSheet
          tx={deleteTxRecord}
          theme={theme}
          accent={accent}
          onCancel={() => setConfirmDelete(null)}
          onConfirm={() => deleteTx(deleteTxRecord.id)}
        />
      )}
      {editingBudget && (
        <EditBudgetSheet
          budgets={budgets}
          txs={txs}
          theme={theme}
          accent={accent}
          onClose={() => setEditingBudget(false)}
          onSave={(b) => {
            setBudgets(b);
            setEditingBudget(false);
          }}
        />
      )}
    </Screen>
  );
}

// ─────────────────────────────────────────────────────────────
// OVERVIEW BODY — forecast + 5 most recent tx, with See all
// ─────────────────────────────────────────────────────────────
function OverviewBody({
  theme,
  accent,
  txs,
  budgets,
  onTxClick,
  onSeeAll,
  onAskHimma,
  onOpenPaywall,
}) {
  const snap = getBudgetSnapshot(txs, budgets);
  const isPro = SUBSCRIPTION.status === "active";

  // Most recent first — TRANSACTIONS are already roughly newest-to-oldest by date.
  const recent = txs.slice(0, 5);

  return (
    <>
      <div style={{ padding: "0 16px 14px" }}>
        <ForecastCard
          theme={theme}
          accent={accent}
          snap={snap}
          isPro={isPro}
          onAskHimma={onAskHimma}
          onOpenPaywall={onOpenPaywall}
        />
      </div>

      {/* Recent transactions header + See all */}
      <div
        style={{
          padding: "0 20px 8px",
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
        }}
      >
        <SectionLabel theme={theme}>Recent transactions</SectionLabel>
        <button
          onClick={onSeeAll}
          style={{
            background: "transparent",
            border: "none",
            cursor: "pointer",
            color: theme.textDim,
            fontFamily: FONTS.ui,
            fontSize: 12,
            display: "flex",
            alignItems: "center",
            gap: 3,
          }}
        >
          See all <Ico.chevR size={12} />
        </button>
      </div>

      <div style={{ padding: "0 16px" }}>
        <Card theme={theme} padded={false}>
          {recent.map((t, i) => (
            <button
              key={t.id}
              onClick={() => onTxClick(t.id)}
              style={{
                width: "100%",
                textAlign: "left",
                background: "transparent",
                border: "none",
                cursor: "pointer",
                display: "flex",
                alignItems: "center",
                gap: 12,
                padding: "11px 14px",
                borderBottom:
                  i < recent.length - 1 ? `0.5px solid ${theme.line}` : "none",
                color: theme.text,
              }}
            >
              <CategoryIcon
                category={t.category}
                theme={theme}
                accent={accent}
                size={32}
              />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div
                  style={{
                    fontSize: 13.5,
                    color: theme.text,
                    fontWeight: 500,
                    whiteSpace: "nowrap",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                  }}
                >
                  {t.merchant}
                </div>
              </div>
              <div
                style={{
                  fontFamily: FONTS.mono,
                  fontSize: 13,
                  color: t.amount >= 0 ? theme.positive : theme.text,
                  fontVariantNumeric: "tabular-nums",
                  fontWeight: 500,
                  whiteSpace: "nowrap",
                }}
              >
                {t.amount >= 0 ? "+" : "−"}
                {fmtAED(Math.abs(t.amount), {
                  decimals: Math.abs(t.amount) < 1000 ? 2 : 0,
                })}
              </div>
            </button>
          ))}
        </Card>
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// BUDGET BODY — moved out into its own view
// ─────────────────────────────────────────────────────────────
function BudgetBody({ theme, accent, txs, budgets, onEditBudget }) {
  const snap = getBudgetSnapshot(txs, budgets);
  return (
    <>
      <div style={{ padding: "0 16px 12px" }}>
        <SpendVsBudgetCard theme={theme} accent={accent} snap={snap} />
      </div>

      <div style={{ padding: "0 16px 14px" }}>
        <Card
          theme={theme}
          padded={false}
          style={{ padding: "14px 14px 12px" }}
        >
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              padding: "0 4px 12px",
            }}
          >
            <SectionLabel theme={theme}>Categories</SectionLabel>
            <button
              onClick={onEditBudget}
              style={{
                background: "transparent",
                border: `0.5px solid ${theme.line2}`,
                borderRadius: 999,
                padding: "5px 10px",
                color: theme.text,
                fontSize: 11,
                fontFamily: FONTS.ui,
                cursor: "pointer",
                display: "flex",
                alignItems: "center",
                gap: 4,
                whiteSpace: "nowrap",
              }}
            >
              <Ico.target size={11} /> Edit budget
            </button>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {snap.items.map((it) => (
              <BudgetBar
                key={it.category}
                item={it}
                theme={theme}
                accent={accent}
              />
            ))}
          </div>
        </Card>
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// ALL BODY (full transaction list with filters)
// ─────────────────────────────────────────────────────────────
function AllBody({ theme, accent, txs, onTxClick }) {
  const [cat, setCat] = React.useState("All");
  const [q, setQ] = React.useState("");
  const [duration, setDuration] = React.useState("all");

  const filtered = txs.filter(
    (t) =>
      (cat === "All" || t.category === cat) &&
      (q === "" || t.merchant.toLowerCase().includes(q.toLowerCase())),
  );

  const spend = filtered
    .filter((t) => t.amount < 0)
    .reduce((s, t) => s + Math.abs(t.amount), 0);
  const income = filtered
    .filter((t) => t.amount > 0)
    .reduce((s, t) => s + t.amount, 0);

  return (
    <>
      {/* Duration filter */}
      <div
        style={{
          display: "flex",
          gap: 6,
          padding: "0 16px 12px",
          overflowX: "auto",
        }}
      >
        {DURATIONS.map((d) => (
          <Chip
            key={d.key}
            active={duration === d.key}
            onClick={() => setDuration(d.key)}
            theme={theme}
            accent={accent}
          >
            {d.label}
          </Chip>
        ))}
      </div>

      {/* Summary */}
      <div style={{ padding: "0 16px 14px" }}>
        <Card
          theme={theme}
          padded={false}
          style={{ padding: 16, display: "flex", gap: 12 }}
        >
          <div style={{ flex: 1, padding: "4px 0" }}>
            <div
              style={{
                fontFamily: FONTS.mono,
                fontSize: 9.5,
                letterSpacing: 1.2,
                textTransform: "uppercase",
                color: theme.textMute,
              }}
            >
              In
            </div>
            <div
              style={{
                fontFamily: FONTS.display,
                fontSize: 19,
                color: theme.positive,
                marginTop: 2,
                fontVariantNumeric: "tabular-nums",
              }}
            >
              +{fmtAED(income, { compact: true })}
            </div>
          </div>
          <div style={{ width: 0.5, background: theme.line2 }} />
          <div style={{ flex: 1, padding: "4px 0" }}>
            <div
              style={{
                fontFamily: FONTS.mono,
                fontSize: 9.5,
                letterSpacing: 1.2,
                textTransform: "uppercase",
                color: theme.textMute,
              }}
            >
              Out
            </div>
            <div
              style={{
                fontFamily: FONTS.display,
                fontSize: 19,
                color: theme.text,
                marginTop: 2,
                fontVariantNumeric: "tabular-nums",
              }}
            >
              −{fmtAED(spend, { compact: true })}
            </div>
          </div>
          <div style={{ width: 0.5, background: theme.line2 }} />
          <div style={{ flex: 1, padding: "4px 0" }}>
            <div
              style={{
                fontFamily: FONTS.mono,
                fontSize: 9.5,
                letterSpacing: 1.2,
                textTransform: "uppercase",
                color: theme.textMute,
              }}
            >
              Net
            </div>
            <div
              style={{
                fontFamily: FONTS.display,
                fontSize: 19,
                color: accent,
                marginTop: 2,
                fontVariantNumeric: "tabular-nums",
              }}
            >
              {income - spend >= 0 ? "+" : "−"}
              {fmtAED(Math.abs(income - spend), { compact: true })}
            </div>
          </div>
        </Card>
      </div>

      {/* Search */}
      <div style={{ padding: "0 16px 10px" }}>
        <div
          style={{
            background: theme.surface,
            border: `0.5px solid ${theme.line}`,
            borderRadius: 14,
            padding: "10px 14px",
            display: "flex",
            gap: 10,
            alignItems: "center",
          }}
        >
          <Ico.search size={15} stroke={theme.textMute} />
          <input
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="Search merchants"
            style={{
              flex: 1,
              background: "transparent",
              border: "none",
              outline: "none",
              color: theme.text,
              fontSize: 13,
              fontFamily: FONTS.ui,
            }}
          />
          {q && (
            <button
              onClick={() => setQ("")}
              style={{
                background: "transparent",
                border: "none",
                color: theme.textMute,
                cursor: "pointer",
              }}
            >
              <Ico.close size={13} />
            </button>
          )}
        </div>
      </div>

      {/* Category chips */}
      <div
        style={{
          display: "flex",
          gap: 6,
          padding: "4px 16px 14px",
          overflowX: "auto",
        }}
      >
        {CATEGORIES.map((c) => (
          <Chip
            key={c}
            active={cat === c}
            onClick={() => setCat(c)}
            theme={theme}
            accent={accent}
          >
            {c}
          </Chip>
        ))}
      </div>

      <TransactionsFeed
        theme={theme}
        accent={accent}
        txs={filtered}
        onTxClick={onTxClick}
      />
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// Shared: transactions feed (grouped by date)
// ─────────────────────────────────────────────────────────────
function TransactionsFeed({ theme, accent, txs, onTxClick, hideEmpty }) {
  const groups = {};
  txs.forEach((t) => {
    if (!groups[t.date]) groups[t.date] = [];
    groups[t.date].push(t);
  });

  return (
    <div style={{ padding: "0 16px" }}>
      {Object.keys(groups).length === 0 && !hideEmpty && (
        <div
          style={{
            padding: 60,
            textAlign: "center",
            color: theme.textMute,
            fontFamily: FONTS.mono,
            fontSize: 11,
          }}
        >
          No transactions match.
        </div>
      )}
      {Object.entries(groups).map(([date, rows]) => {
        const dayTotal = rows.reduce((s, t) => s + t.amount, 0);
        return (
          <div key={date} style={{ marginBottom: 14 }}>
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                padding: "4px 6px 8px",
              }}
            >
              <div
                style={{
                  fontFamily: FONTS.mono,
                  fontSize: 10,
                  color: theme.textMute,
                  textTransform: "uppercase",
                  letterSpacing: 1.2,
                }}
              >
                {date}
              </div>
              <div
                style={{
                  fontFamily: FONTS.mono,
                  fontSize: 10,
                  color: theme.textMute,
                }}
              >
                {dayTotal >= 0 ? "+" : "−"}
                <Dh /> {fmtAED(Math.abs(dayTotal))}
              </div>
            </div>
            <Card theme={theme} padded={false}>
              {rows.map((t, i) => (
                <button
                  key={t.id}
                  onClick={() => onTxClick(t.id)}
                  style={{
                    width: "100%",
                    textAlign: "left",
                    background: "transparent",
                    border: "none",
                    cursor: "pointer",
                    display: "flex",
                    alignItems: "center",
                    gap: 12,
                    padding: "11px 14px",
                    borderBottom:
                      i < rows.length - 1
                        ? `0.5px solid ${theme.line}`
                        : "none",
                    color: theme.text,
                  }}
                >
                  <CategoryIcon
                    category={t.category}
                    theme={theme}
                    accent={accent}
                    size={32}
                  />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div
                      style={{
                        fontSize: 13.5,
                        color: theme.text,
                        fontWeight: 500,
                        whiteSpace: "nowrap",
                        overflow: "hidden",
                        textOverflow: "ellipsis",
                      }}
                    >
                      {t.merchant}
                    </div>
                    <div
                      style={{
                        fontSize: 11,
                        color: theme.textMute,
                        fontFamily: FONTS.mono,
                        marginTop: 2,
                      }}
                    >
                      {t.category} · {t.account}
                    </div>
                  </div>
                  <div
                    style={{
                      fontFamily: FONTS.mono,
                      fontSize: 13,
                      color: t.amount >= 0 ? theme.positive : theme.text,
                      fontVariantNumeric: "tabular-nums",
                      fontWeight: 500,
                      whiteSpace: "nowrap",
                    }}
                  >
                    {t.amount >= 0 ? "+" : "−"}
                    {fmtAED(Math.abs(t.amount), {
                      decimals: Math.abs(t.amount) < 1000 ? 2 : 0,
                    })}
                  </div>
                </button>
              ))}
            </Card>
          </div>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Month progress
// ─────────────────────────────────────────────────────────────
function MonthProgressCard({ theme, accent }) {
  const pct = (TODAY.day / TODAY.daysInMonth) * 100;
  return (
    <Card
      theme={theme}
      padded={false}
      style={{
        padding: "14px 16px 14px",
        position: "relative",
        overflow: "hidden",
      }}
    >
      {/* top thin progress bar */}
      <div
        style={{
          position: "absolute",
          top: 0,
          left: 0,
          right: 0,
          height: 2,
          background: theme.surface2,
        }}
      >
        <div style={{ height: "100%", width: `${pct}%`, background: accent }} />
      </div>
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
        }}
      >
        <div>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 9.5,
              letterSpacing: 1.5,
              textTransform: "uppercase",
              color: theme.textMute,
            }}
          >
            {TODAY.monthName}
          </div>
          <div
            style={{
              fontFamily: FONTS.display,
              fontSize: 16,
              color: theme.text,
              marginTop: 2,
              letterSpacing: -0.2,
            }}
          >
            Day <b style={{ fontWeight: 600 }}>{TODAY.day}</b> of{" "}
            {TODAY.daysInMonth}
          </div>
        </div>
        <div style={{ textAlign: "right" }}>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 9.5,
              letterSpacing: 1.2,
              textTransform: "uppercase",
              color: theme.textMute,
            }}
          >
            Remaining
          </div>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 13.5,
              color: theme.textDim,
              marginTop: 2,
              fontVariantNumeric: "tabular-nums",
            }}
          >
            {TODAY.daysInMonth - TODAY.day} days
          </div>
        </div>
      </div>
    </Card>
  );
}

// ─────────────────────────────────────────────────────────────
// Spend vs budget hero card
// ─────────────────────────────────────────────────────────────
function SpendVsBudgetCard({ theme, accent, snap }) {
  const ahead = snap.paceDeltaPct < 0; // spending below pace
  const over = snap.totalSpent > snap.totalBudget;
  const paceColor = over
    ? theme.negative
    : ahead
      ? theme.positive
      : theme.warning;
  const paceWord = over ? "over budget" : ahead ? "under pace" : "over pace";

  return (
    <Card theme={theme} style={{ padding: 18 }}>
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "flex-start",
        }}
      >
        <div>
          <SectionLabel theme={theme}>Spent so far</SectionLabel>
          <BigNumber
            value={snap.totalSpent}
            theme={theme}
            accent={accent}
            size={30}
            decimals={0}
          />
        </div>
        <div style={{ textAlign: "right" }}>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 9.5,
              letterSpacing: 1.2,
              textTransform: "uppercase",
              color: theme.textMute,
            }}
          >
            Of budget
          </div>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 14,
              color: theme.text,
              marginTop: 4,
              fontVariantNumeric: "tabular-nums",
            }}
          >
            <Dh /> {fmtAED(snap.totalBudget, { compact: true })}
          </div>
        </div>
      </div>

      {/* Combined progress bar */}
      <div style={{ marginTop: 14 }}>
        <BudgetTrack
          theme={theme}
          accent={accent}
          spent={snap.totalSpent}
          budget={snap.totalBudget}
          projected={snap.totalProjected}
        />
      </div>

      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 8,
          marginTop: 12,
          fontFamily: FONTS.mono,
          fontSize: 11.5,
        }}
      >
        <span style={{ color: paceColor, fontWeight: 600 }}>
          {snap.paceDeltaPct >= 0 ? "+" : ""}
          {snap.paceDeltaPct.toFixed(1)}%
        </span>
        <span style={{ color: theme.textDim }}>
          {paceWord} · day {TODAY.day} of {TODAY.daysInMonth}
        </span>
      </div>
    </Card>
  );
}

// Single bar with three layers: spent (solid), projected-extension (lighter), and a cap marker.
// Track width is max(budget, projected) so it always fits.
function BudgetTrack({ theme, accent, spent, budget, projected }) {
  const trackVal = Math.max(budget, projected);
  const spentPct = (spent / trackVal) * 100;
  const projExtraPct = (Math.max(0, projected - spent) / trackVal) * 100;
  const capPct = (budget / trackVal) * 100;
  const overProj = projected > budget;
  const fillColor = overProj ? theme.warning : theme.positive;
  const ghostColor = overProj ? theme.warning : theme.textDim;

  return (
    <div
      style={{
        position: "relative",
        height: 8,
        background: theme.surface2,
        borderRadius: 4,
        overflow: "visible",
      }}
    >
      {/* solid spent */}
      <div
        style={{
          position: "absolute",
          top: 0,
          bottom: 0,
          left: 0,
          width: `${spentPct}%`,
          background: fillColor,
          borderRadius: 4,
        }}
      />
      {/* projected extension */}
      <div
        style={{
          position: "absolute",
          top: 0,
          bottom: 0,
          left: `${spentPct}%`,
          width: `${projExtraPct}%`,
          background: ghostColor,
          opacity: 0.28,
          borderRadius: 4,
        }}
      />
      {/* cap marker */}
      <div
        style={{
          position: "absolute",
          top: -3,
          bottom: -3,
          left: `${capPct}%`,
          width: 1.5,
          background: theme.text,
          opacity: 0.55,
        }}
      />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Per-category budget bar row
// ─────────────────────────────────────────────────────────────
function BudgetBar({ item, theme, accent }) {
  const overProj = item.projected > item.budget;
  const projColor = overProj ? theme.negative : theme.textDim;
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 12,
        padding: "4px 4px",
      }}
    >
      <CategoryIcon
        category={item.category}
        theme={theme}
        accent={accent}
        size={32}
      />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "baseline",
            gap: 8,
          }}
        >
          <span style={{ fontSize: 13, color: theme.text, fontWeight: 500 }}>
            {item.category}
          </span>
          <span
            style={{
              fontFamily: FONTS.mono,
              fontSize: 11.5,
              color: theme.text,
              fontVariantNumeric: "tabular-nums",
              whiteSpace: "nowrap",
            }}
          >
            <Dh /> {fmtAED(item.spent, { decimals: item.spent < 1000 ? 0 : 0 })}
            <span style={{ color: theme.textMute }}>
              {" "}
              / {fmtAED(item.budget, { compact: true })}
            </span>
          </span>
        </div>
        <div style={{ marginTop: 6 }}>
          <BudgetTrack
            theme={theme}
            accent={accent}
            spent={item.spent}
            budget={item.budget}
            projected={item.projected}
          />
        </div>
        <div
          style={{
            marginTop: 5,
            fontFamily: FONTS.mono,
            fontSize: 9.5,
            color: theme.textMute,
            display: "flex",
            justifyContent: "space-between",
          }}
        >
          <span>{(item.pct * 100).toFixed(0)}% used</span>
          <span style={{ color: projColor }}>
            {overProj ? (
              <>
                proj. <Dh /> {fmtAED(item.projected, { compact: true })} · +
                {fmtAED(item.projected - item.budget)} over
              </>
            ) : (
              <>
                proj. <Dh /> {fmtAED(item.projected, { compact: true })} ·{" "}
                {fmtAED(item.budget - item.projected)} left
              </>
            )}
          </span>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Forecast card — Pro-gated
// ─────────────────────────────────────────────────────────────
function ForecastCard({
  theme,
  accent,
  snap,
  isPro,
  onAskHimma,
  onOpenPaywall,
}) {
  const over = snap.overUnder > 0;

  if (!isPro) {
    return (
      <Card
        theme={theme}
        style={{ padding: 18, borderStyle: "dashed", position: "relative" }}
      >
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 8,
            marginBottom: 6,
          }}
        >
          <Ico.lock size={12} stroke={theme.textMute} />
          <SectionLabel theme={theme}>Month-end forecast</SectionLabel>
        </div>
        <div
          style={{
            fontFamily: FONTS.display,
            fontSize: 22,
            color: theme.textMute,
            letterSpacing: -0.4,
            filter: "blur(5px)",
            userSelect: "none",
          }}
        >
          <Dh /> 4,351
        </div>
        <button
          onClick={onOpenPaywall}
          style={{
            marginTop: 14,
            width: "100%",
            background: accent,
            color: theme.bg,
            border: "none",
            padding: "12px",
            borderRadius: 12,
            fontFamily: FONTS.ui,
            fontSize: 13,
            fontWeight: 600,
            cursor: "pointer",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            gap: 6,
          }}
        >
          Unlock with Pro <Ico.arrowUR size={13} stroke={theme.bg} />
        </button>
      </Card>
    );
  }

  const stats = getForecastWindowStats();
  const fullStats = {
    avg: stats.soFar.avg + stats.remaining.avg,
    min: stats.soFar.min + stats.remaining.min,
    max: stats.soFar.max + stats.remaining.max,
  };

  const rows = [
    {
      key: "soFar",
      label: "Spend so far",
      range: `Day [1-${TODAY.day}]`,
      value: snap.totalSpent,
      stats: stats.soFar,
      kind: "actual",
    },
    {
      key: "remaining",
      label: "Spend remaining",
      range: `Day [${TODAY.day + 1}-${TODAY.daysInMonth}]`,
      stats: stats.remaining,
      kind: "projected",
    },
    {
      key: "forecast",
      label: "Month-end forecast",
      range: `Day [1-${TODAY.daysInMonth}]`,
      value: snap.totalProjected,
      stats: fullStats,
      kind: "highlight",
    },
  ];

  return (
    <Card
      theme={theme}
      style={{ padding: 18, position: "relative", overflow: "hidden" }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 8,
          marginBottom: 12,
        }}
      >
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <Ico.sparkles size={12} stroke={accent} />
          <SectionLabel theme={theme}>Month-end forecast</SectionLabel>
        </div>
        <div
          style={{
            fontFamily: FONTS.mono,
            fontSize: 9,
            color: theme.textMute,
            letterSpacing: 0.5,
          }}
        >
          Last {stats.monthsCount} mo
        </div>
      </div>

      <ForecastTable theme={theme} accent={accent} rows={rows} />

      {over && (
        <button
          onClick={onAskHimma}
          style={{
            marginTop: 14,
            width: "100%",
            background: `${accent}14`,
            color: theme.text,
            border: `0.5px solid ${accent}55`,
            borderRadius: 12,
            padding: "11px 14px",
            cursor: "pointer",
            display: "flex",
            alignItems: "center",
            gap: 10,
            fontFamily: FONTS.ui,
            fontSize: 13,
            textAlign: "left",
          }}
        >
          <div
            style={{
              width: 24,
              height: 24,
              borderRadius: 12,
              background: `${accent}22`,
              color: accent,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              flexShrink: 0,
            }}
          >
            <Ico.sparkles size={12} />
          </div>
          <span style={{ flex: 1, color: theme.text }}>
            Ask Himma where to cut
          </span>
          <Ico.chevR size={13} stroke={theme.textDim} />
        </button>
      )}
    </Card>
  );
}

// Consolidated 3-row forecast table: spend so far, spend remaining, and a
// highlighted month-end forecast row, each compared against avg/min/max history.
function ForecastTable({ theme, accent, rows }) {
  const fmt = (v) =>
    fmtAED(Math.round(v), { compact: v >= 10000, decimals: 0 });
  const cols = "3fr 0.9fr 0.9fr 0.9fr 1fr";
  const sepRight = `0.5px solid ${theme.line}`;

  const headerCell = (label, separator = false) => (
    <div
      style={{
        fontFamily: FONTS.mono,
        fontSize: 8.5,
        letterSpacing: 1,
        textTransform: "uppercase",
        color: theme.textMute,
        borderRight: separator ? sepRight : "none",
        paddingRight: separator ? 12 : 0,
        display: "flex",
        alignItems: "center",
        justifyContent: "flex-end",
      }}
    >
      {label}
    </div>
  );

  const statCell = (value) => (
    <div
      style={{
        fontFamily: FONTS.mono,
        fontSize: 10,
        color: theme.textDim,
        fontVariantNumeric: "tabular-nums",
        display: "flex",
        alignItems: "flex-start",
        justifyContent: "flex-end",
      }}
    >
      {fmt(value)}
    </div>
  );

  return (
    <div
      style={{
        border: `0.5px solid ${theme.line}`,
        borderRadius: 12,
        overflow: "hidden",
      }}
    >
      <div
        style={{
          display: "grid",
          gridTemplateColumns: cols,
          columnGap: 12,
          padding: "8px 12px",
          background: theme.surface2,
          borderBottom: `0.5px solid ${theme.line}`,
        }}
      >
        <div
          style={{
            fontFamily: FONTS.mono,
            fontSize: 8.5,
            letterSpacing: 1,
            textTransform: "uppercase",
            color: theme.textMute,
            display: "flex",
            alignItems: "center",
          }}
        >
          Period
        </div>
        {headerCell("Min")}
        {headerCell("Max")}
        {headerCell("Avg", true)}
        {headerCell("You")}
      </div>

      {rows.map((row, i) => {
        const highlight = row.kind === "highlight";
        const hasValue = row.value !== undefined;
        const deltaPct =
          hasValue && row.stats.avg > 0
            ? ((row.value - row.stats.avg) / row.stats.avg) * 100
            : null;
        const deltaOver = deltaPct !== null && deltaPct >= 0;
        const deltaColor =
          deltaPct === null
            ? theme.textMute
            : deltaOver
              ? theme.negative
              : theme.positive;

        return (
          <div
            key={row.key}
            style={{
              display: "grid",
              gridTemplateColumns: cols,
              columnGap: 12,
              alignItems: "stretch",
              padding: "10px 12px",
              background: highlight ? `${accent}10` : "transparent",
              borderTop: i === 0 ? "none" : `0.5px solid ${theme.line}`,
            }}
          >
            <div
              style={{
                display: "flex",
                flexDirection: "column",
                justifyContent: "center",
              }}
            >
              <div
                style={{
                  fontFamily: FONTS.ui,
                  fontSize: 12,
                  color: theme.text,
                  fontWeight: highlight ? 600 : 500,
                }}
              >
                {row.label}
              </div>
              <div
                style={{
                  fontFamily: FONTS.mono,
                  fontSize: 9.5,
                  color: theme.textMute,
                  marginTop: 2,
                  letterSpacing: 0.3,
                }}
              >
                {row.range}
              </div>
            </div>
            {statCell(row.stats.min)}
            {statCell(row.stats.max)}
            <div
              style={{
                fontFamily: FONTS.mono,
                fontSize: 10,
                color: theme.textDim,
                fontVariantNumeric: "tabular-nums",
                borderRight: sepRight,
                paddingRight: 12,
                display: "flex",
                alignItems: "flex-start",
                justifyContent: "flex-end",
              }}
            >
              {fmt(row.stats.avg)}
            </div>
            <div
              style={{
                display: "flex",
                flexDirection: "column",
                alignItems: "flex-end",
                justifyContent: "flex-start",
              }}
            >
              <div
                style={{
                  fontFamily: FONTS.mono,
                  fontSize: 10,
                  color: theme.text,
                  fontWeight: 600,
                  fontVariantNumeric: "tabular-nums",
                }}
              >
                {hasValue ? fmt(row.value) : ""}
              </div>
              {deltaPct !== null && (
                <div
                  style={{
                    fontFamily: FONTS.mono,
                    fontSize: 9.5,
                    color: deltaColor,
                    fontWeight: 600,
                    fontVariantNumeric: "tabular-nums",
                    marginTop: 2,
                    letterSpacing: 0.3,
                  }}
                >
                  {deltaOver ? "+" : "−"}
                  {Math.abs(deltaPct).toFixed(0)}%
                </div>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Edit budget sheet
// ─────────────────────────────────────────────────────────────
function EditBudgetSheet({ budgets, txs, theme, accent, onClose, onSave }) {
  const [draft, setDraft] = React.useState(budgets);
  const spent = getMonthSpendByCategory(txs);
  const total = Object.values(draft).reduce((s, v) => s + (Number(v) || 0), 0);

  const setVal = (cat, v) =>
    setDraft((d) => ({ ...d, [cat]: v === "" ? 0 : Number(v) }));

  return (
    <div
      onClick={onClose}
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 120,
        background: "rgba(0,0,0,0.55)",
        display: "flex",
        alignItems: "flex-end",
        animation: "himma-fade 200ms",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "100%",
          background: theme.surface,
          borderRadius: "24px 24px 0 0",
          borderTop: `0.5px solid ${theme.line2}`,
          padding: "10px 20px 34px",
          animation: "himma-slide 260ms cubic-bezier(.2,.8,.25,1)",
          maxHeight: "88%",
          overflow: "auto",
        }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            paddingBottom: 10,
          }}
        >
          <div
            style={{
              width: 40,
              height: 4,
              borderRadius: 2,
              background: theme.line2,
            }}
          />
        </div>

        <div
          style={{
            fontFamily: FONTS.display,
            fontSize: 22,
            color: theme.text,
            letterSpacing: -0.4,
          }}
        >
          Edit budget
        </div>
        <div
          style={{
            fontSize: 12.5,
            color: theme.textDim,
            marginTop: 4,
            fontFamily: FONTS.ui,
          }}
        >
          Monthly caps for {TODAY.monthName}. Suggestions are your trailing
          3-month average.
        </div>

        <div
          style={{
            marginTop: 18,
            display: "flex",
            flexDirection: "column",
            gap: 12,
          }}
        >
          {BUDGET_CATEGORIES.map((cat) => {
            const sp = spent[cat];
            const suggested = SPEND_3MO_AVG[cat];
            return (
              <div
                key={cat}
                style={{
                  background: theme.surface2,
                  border: `0.5px solid ${theme.line}`,
                  borderRadius: 14,
                  padding: "12px 14px",
                }}
              >
                <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                  <CategoryIcon
                    category={cat}
                    theme={theme}
                    accent={accent}
                    size={28}
                  />
                  <div style={{ flex: 1 }}>
                    <div
                      style={{
                        fontSize: 13,
                        fontWeight: 500,
                        color: theme.text,
                      }}
                    >
                      {cat}
                    </div>
                    <div
                      style={{
                        fontFamily: FONTS.mono,
                        fontSize: 10,
                        color: theme.textMute,
                        marginTop: 2,
                      }}
                    >
                      Spent <Dh /> {fmtAED(sp)} so far · 3-mo avg <Dh />{" "}
                      {fmtAED(suggested, { compact: true })}
                    </div>
                  </div>
                </div>
                <div
                  style={{
                    marginTop: 10,
                    display: "flex",
                    alignItems: "center",
                    gap: 8,
                    background: theme.surface,
                    border: `0.5px solid ${theme.line2}`,
                    borderRadius: 10,
                    padding: "8px 12px",
                  }}
                >
                  <span
                    style={{
                      fontFamily: FONTS.mono,
                      fontSize: 11,
                      color: theme.textMute,
                      display: "inline-flex",
                      alignItems: "center",
                    }}
                  >
                    <Dh />
                  </span>
                  <input
                    type="number"
                    value={draft[cat]}
                    onChange={(e) => setVal(cat, e.target.value)}
                    style={{
                      flex: 1,
                      background: "transparent",
                      border: "none",
                      outline: "none",
                      color: theme.text,
                      fontSize: 14,
                      fontFamily: FONTS.mono,
                      fontVariantNumeric: "tabular-nums",
                      minWidth: 0,
                    }}
                  />
                  <button
                    onClick={() => setVal(cat, suggested)}
                    style={{
                      background: "transparent",
                      border: `0.5px solid ${theme.line2}`,
                      borderRadius: 999,
                      padding: "4px 9px",
                      color: theme.textDim,
                      cursor: "pointer",
                      fontFamily: FONTS.mono,
                      fontSize: 9.5,
                      letterSpacing: 0.4,
                      textTransform: "uppercase",
                    }}
                  >
                    Use 3-mo
                  </button>
                </div>
              </div>
            );
          })}
        </div>

        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            marginTop: 18,
            padding: "0 4px",
          }}
        >
          <span
            style={{
              fontFamily: FONTS.mono,
              fontSize: 10.5,
              color: theme.textMute,
              textTransform: "uppercase",
              letterSpacing: 1,
            }}
          >
            Total cap
          </span>
          <span
            style={{
              fontFamily: FONTS.mono,
              fontSize: 14,
              color: theme.text,
              fontVariantNumeric: "tabular-nums",
            }}
          >
            <Dh /> {fmtAED(total)}
          </span>
        </div>

        <button
          onClick={() => onSave(draft)}
          style={{
            marginTop: 14,
            width: "100%",
            background: accent,
            color: theme.bg,
            border: "none",
            padding: "14px",
            borderRadius: 14,
            fontFamily: FONTS.ui,
            fontSize: 14,
            fontWeight: 600,
            cursor: "pointer",
          }}
        >
          Save budget
        </button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Existing actions sheet + category picker (unchanged)
// ─────────────────────────────────────────────────────────────
function TxActionsSheet({
  tx,
  theme,
  accent,
  onClose,
  onReCategorize,
  onDelete,
}) {
  return (
    <div
      onClick={onClose}
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 120,
        background: "rgba(0,0,0,0.55)",
        display: "flex",
        alignItems: "flex-end",
        animation: "himma-fade 200ms",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "100%",
          background: theme.surface,
          borderRadius: "24px 24px 0 0",
          borderTop: `0.5px solid ${theme.line2}`,
          padding: "10px 20px 34px",
          animation: "himma-slide 260ms cubic-bezier(.2,.8,.25,1)",
        }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            paddingBottom: 14,
          }}
        >
          <div
            style={{
              width: 40,
              height: 4,
              borderRadius: 2,
              background: theme.line2,
            }}
          />
        </div>

        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 12,
            padding: "4px 0 18px",
            borderBottom: `0.5px solid ${theme.line}`,
          }}
        >
          <CategoryIcon
            category={tx.category}
            theme={theme}
            accent={accent}
            size={42}
          />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 15, color: theme.text, fontWeight: 500 }}>
              {tx.merchant}
            </div>
            <div
              style={{
                fontSize: 11,
                color: theme.textMute,
                fontFamily: FONTS.mono,
                marginTop: 2,
              }}
            >
              {tx.category} · {tx.account} · {tx.date}
            </div>
          </div>
          <div
            style={{
              fontFamily: FONTS.mono,
              fontSize: 15,
              color: tx.amount >= 0 ? theme.positive : theme.text,
            }}
          >
            {tx.amount >= 0 ? "+" : "−"}
            {fmtAED(Math.abs(tx.amount), {
              decimals: Math.abs(tx.amount) < 1000 ? 2 : 0,
            })}
          </div>
        </div>

        <div
          style={{
            display: "flex",
            flexDirection: "column",
            gap: 6,
            marginTop: 14,
          }}
        >
          <ActionRow
            icon="target"
            label="Change category"
            theme={theme}
            accent={accent}
            onClick={onReCategorize}
          />
          <div style={{ height: 4 }} />
          <ActionRow
            icon="close"
            label="Delete transaction"
            theme={theme}
            accent={theme.negative}
            destructive
            onClick={onDelete}
          />
        </div>
      </div>
    </div>
  );
}

function ActionRow({ icon, label, theme, accent, destructive, onClick }) {
  const Icon = Ico[icon];
  return (
    <button
      onClick={onClick}
      style={{
        background: theme.surface2,
        border: `0.5px solid ${theme.line}`,
        borderRadius: 12,
        padding: "12px 14px",
        display: "flex",
        alignItems: "center",
        gap: 12,
        cursor: "pointer",
        textAlign: "left",
        color: theme.text,
      }}
    >
      <div
        style={{
          width: 32,
          height: 32,
          borderRadius: 8,
          background: theme.surface3,
          color: accent,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          flexShrink: 0,
        }}
      >
        <Icon size={14} />
      </div>
      <div style={{ flex: 1 }}>
        <div
          style={{
            fontSize: 13,
            fontWeight: 500,
            color: destructive ? theme.negative : theme.text,
          }}
        >
          {label}
        </div>
      </div>
      <Ico.chevR size={12} stroke={theme.textDim} />
    </button>
  );
}

// Delete confirmation — discloses metric impact before removing the tx.
function DeleteConfirmSheet({ tx, theme, accent, onCancel, onConfirm }) {
  return (
    <div
      onClick={onCancel}
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 140,
        background: "rgba(0,0,0,0.6)",
        display: "flex",
        alignItems: "flex-end",
        animation: "himma-fade 200ms",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "100%",
          background: theme.surface,
          borderRadius: "24px 24px 0 0",
          borderTop: `0.5px solid ${theme.line2}`,
          padding: "10px 20px 28px",
          animation: "himma-slide 260ms cubic-bezier(.2,.8,.25,1)",
        }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            paddingBottom: 14,
          }}
        >
          <div
            style={{
              width: 40,
              height: 4,
              borderRadius: 2,
              background: theme.line2,
            }}
          />
        </div>

        <div
          style={{
            width: 48,
            height: 48,
            borderRadius: 24,
            margin: "4px auto 14px",
            background: `${theme.negative}18`,
            color: theme.negative,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Ico.close size={22} sw={2.2} />
        </div>

        <div
          style={{
            fontFamily: FONTS.display,
            fontSize: 20,
            color: theme.text,
            letterSpacing: -0.3,
            textAlign: "center",
          }}
        >
          Delete this transaction?
        </div>
        <div
          style={{
            fontSize: 13,
            color: theme.textDim,
            marginTop: 10,
            lineHeight: 1.5,
            textAlign: "center",
            padding: "0 6px",
          }}
        >
          Your spending, budget pacing and other metrics will be readjusted as
          if <b style={{ color: theme.text }}>{tx.merchant}</b> (
          {tx.amount >= 0 ? "+" : "−"}
          {fmtAED(Math.abs(tx.amount), {
            decimals: Math.abs(tx.amount) < 1000 ? 2 : 0,
          })}
          ) never happened. Are you OK with that?
        </div>

        <div style={{ display: "flex", gap: 10, marginTop: 22 }}>
          <button
            onClick={onCancel}
            style={{
              flex: 1,
              background: "transparent",
              border: `0.5px solid ${theme.line2}`,
              borderRadius: 14,
              padding: "13px",
              color: theme.text,
              fontFamily: FONTS.ui,
              fontSize: 13.5,
              fontWeight: 500,
              cursor: "pointer",
            }}
          >
            Cancel
          </button>
          <button
            onClick={onConfirm}
            style={{
              flex: 1,
              background: theme.negative,
              border: "none",
              borderRadius: 14,
              padding: "13px",
              color: "#fff",
              fontFamily: FONTS.ui,
              fontSize: 13.5,
              fontWeight: 600,
              cursor: "pointer",
            }}
          >
            Delete
          </button>
        </div>
      </div>
    </div>
  );
}

function CategoryPicker({ tx, theme, accent, onClose, onPick }) {
  return (
    <div
      onClick={onClose}
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 130,
        background: "rgba(0,0,0,0.6)",
        display: "flex",
        alignItems: "flex-end",
        animation: "himma-fade 200ms",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "100%",
          background: theme.surface,
          borderRadius: "24px 24px 0 0",
          borderTop: `0.5px solid ${theme.line2}`,
          padding: "10px 20px 34px",
          animation: "himma-slide 260ms cubic-bezier(.2,.8,.25,1)",
        }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            paddingBottom: 10,
          }}
        >
          <div
            style={{
              width: 40,
              height: 4,
              borderRadius: 2,
              background: theme.line2,
            }}
          />
        </div>

        <div
          style={{
            fontFamily: FONTS.display,
            fontSize: 20,
            color: theme.text,
            letterSpacing: -0.3,
          }}
        >
          Change category
        </div>

        <div
          style={{
            marginTop: 16,
            display: "grid",
            gridTemplateColumns: "1fr 1fr",
            gap: 8,
          }}
        >
          {EDITABLE_CATS.map((c) => {
            const active = c === tx.category;
            return (
              <button
                key={c}
                onClick={() => onPick(c)}
                style={{
                  background: active ? `${accent}15` : theme.surface2,
                  border: `0.5px solid ${active ? accent + "55" : theme.line}`,
                  borderRadius: 12,
                  padding: "12px 12px",
                  display: "flex",
                  alignItems: "center",
                  gap: 10,
                  cursor: "pointer",
                  textAlign: "left",
                  color: theme.text,
                }}
              >
                <CategoryIcon
                  category={c}
                  theme={theme}
                  accent={accent}
                  size={28}
                />
                <span style={{ fontSize: 12.5, fontWeight: 500, flex: 1 }}>
                  {c}
                </span>
                {active && <Ico.check size={13} stroke={accent} sw={2} />}
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TransactionsScreen });
