;(function () {
/* CashFlowSheet — bottom sheet that handles all three money-movement
   flows: deposit, withdraw, transfer. One modal with a `mode` prop
   that switches the form skeleton:
     deposit  : card → business line
     withdraw : business line → card
     transfer : business line → business line

   Triggered globally via window.openCashFlow(mode) which is wired up
   by App. PortfolioCard (home) and the WalletScreen hero pills both
   call it directly so we skip a layer of prop-drilling.

   On confirm: dispatches deposit/withdraw/transfer through the
   trade-store mutators, fires a toast, closes the sheet. Balances
   propagate live everywhere via useBalances. */

/* iOS-style spring curve — feels more natural than the standard
   Material easing for a sheet sliding up + down. 420ms balances
   "deliberate but not laggy". */
const ANIM_MS = 420;
const EASE = 'cubic-bezier(0.32, 0.72, 0.24, 1)';

/* The four real business lines available. Savings is excluded — it's
   not yet activated in the wallet (still shows the "Activate" CTA). */
const ACCOUNT_OPTIONS = [
  { id: 'trading', label: 'Trading',       color: '#00AFAB' },
  { id: 'gold',    label: 'Gold',          color: '#FAC515' },
  { id: 'wealth',  label: 'Wealth',        color: '#006B67' },
  { id: 'shares',  label: 'Cash Equities', color: '#2E90FA' },
];
const ACCOUNT_LABEL = ACCOUNT_OPTIONS.reduce((m, a) => { m[a.id] = a.label; return m; }, {});

/* Stub card — populated on first render of the deposit/withdraw flow.
   Demo only; no real card storage. */
const CARD = { brand: 'Visa', last4: '8821', name: 'Ariz Raza' };

const TITLES = {
  deposit:  { title: 'Deposit',  cta: 'Confirm deposit',     toast: 'Deposit confirmed' },
  withdraw: { title: 'Withdraw', cta: 'Confirm withdrawal',  toast: 'Withdrawal sent'   },
  transfer: { title: 'Transfer', cta: 'Confirm transfer',    toast: 'Transfer complete' },
};

/* Quick-amount chips ($100 / $500 / $1k / $5k). Tap to set the input
   to that exact value; useful so the user doesn't have to type. */
const QUICK_AMOUNTS = [100, 500, 1000, 5000];

const CloseGlyph = () => (
  <svg width={18} height={18} viewBox="0 0 24 24" fill="none">
    <path d="M6 6l12 12M18 6L6 18" stroke={colors.muted} strokeWidth={2} strokeLinecap="round"/>
  </svg>
);

/* Inline 18px spinner — circular indeterminate via a CSS keyframe.
   Used inside the Confirm button while a deposit is "processing". */
const Spinner = ({ color = '#fff' }) => (
  <svg width={18} height={18} viewBox="0 0 24 24" fill="none" style={{ animation: 'cashFlowSpin 800ms linear infinite' }}>
    <circle cx={12} cy={12} r={9} stroke={color} strokeOpacity={0.25} strokeWidth={3}/>
    <path d="M21 12a9 9 0 0 0-9-9" stroke={color} strokeWidth={3} strokeLinecap="round"/>
  </svg>
);

/* Register the spin keyframe once per session — the spinner uses it
   via `animation`. Idempotent: only inject once. */
if (typeof document !== 'undefined' && !document.getElementById('cash-flow-spin-keyframes')) {
  const s = document.createElement('style');
  s.id = 'cash-flow-spin-keyframes';
  s.textContent = '@keyframes cashFlowSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }';
  document.head.appendChild(s);
}

const ArrowDown = ({ color = '#00AFAB' }) => (
  <svg width={20} height={20} viewBox="0 0 24 24" fill="none">
    <path d="M12 5v14M6 13l6 6 6-6" stroke={color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

/* Format a balance with 2-decimal precision. */
const fmtUSD = (n) => '$' + Number(n || 0).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

/* Card pill — used in deposit (source) and withdraw (destination).
   Visual: dark navy panel with brand + last4 + cardholder. Read-only
   for now since the user said any fake number is fine — saved card
   only. */
const CardPanel = () => (
  <div style={{
    background: 'linear-gradient(135deg, #0E1420 0%, #1F2A3A 100%)',
    borderRadius: '12px',
    padding: '14px 16px',
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    gap: '12px',
  }}>
    <div style={{
      width: '36px', height: '24px',
      borderRadius: '4px',
      backgroundColor: '#1A55E0',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'Gilroy', fontWeight: 800, fontSize: '11px',
      letterSpacing: '0.4px',
      color: '#fff',
      fontStyle: 'italic',
    }}>VISA</div>
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
      <span style={{ fontFamily: 'Gilroy', fontWeight: 600, fontSize: '14px', color: '#fff', fontVariantNumeric: 'tabular-nums' }}>
        {`•••• ${CARD.last4}`}
      </span>
      <span style={{ fontFamily: 'Inter', fontWeight: 400, fontSize: '11px', color: 'rgba(255,255,255,0.65)', marginTop: '2px' }}>
        {`${CARD.brand} · ${CARD.name}`}
      </span>
    </div>
  </div>
);

/* Account selector — row of 4 chips, one per business line. Shows the
   live balance underneath each label so the user has context. */
const AccountChips = ({ value, onChange, exclude }) => (
  <div style={{
    display: 'grid',
    gridTemplateColumns: '1fr 1fr',
    gap: '8px',
  }}>
    {ACCOUNT_OPTIONS.map((acc) => {
      const balances = window.useBalances();
      const balance = balances[acc.id] || 0;
      const selected = value === acc.id;
      const disabled = exclude && exclude === acc.id;
      return (
        <button
          key={acc.id}
          onClick={() => !disabled && onChange(acc.id)}
          disabled={disabled}
          style={{
            border: selected ? `1.5px solid ${acc.color}` : `1px solid ${colors.line}`,
            background: selected ? `${acc.color}1A` : disabled ? '#F9FAFB' : '#fff',
            borderRadius: '12px',
            padding: '12px',
            cursor: disabled ? 'not-allowed' : 'pointer',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'flex-start',
            gap: '4px',
            opacity: disabled ? 0.45 : 1,
            margin: 0,
            font: 'inherit',
            color: 'inherit',
            textAlign: 'left',
          }}
        >
          <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '6px' }}>
            <span style={{
              width: '8px', height: '8px', borderRadius: '4px',
              backgroundColor: acc.color, display: 'inline-block',
            }}/>
            <span style={{
              fontFamily: 'Gilroy',
              fontWeight: 600,
              fontSize: '13px',
              color: colors.ink,
            }}>{acc.label}</span>
          </div>
          <span style={{
            fontFamily: 'Inter',
            fontWeight: 400,
            fontSize: '11px',
            color: colors.muted2,
            fontVariantNumeric: 'tabular-nums',
          }}>{fmtUSD(balance)}</span>
        </button>
      );
    })}
  </div>
);

/* Amount input — numeric input with quick-pick chips below. */
const AmountField = ({ value, setValue, max }) => {
  const onInput = (e) => {
    /* Strip everything that isn't a digit or '.'; keep at most one dot. */
    let s = e.target.value.replace(/[^0-9.]/g, '');
    const i = s.indexOf('.');
    if (i >= 0) s = s.slice(0, i + 1) + s.slice(i + 1).replace(/\./g, '');
    setValue(s);
  };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
      <div style={{
        display: 'flex',
        flexDirection: 'row',
        alignItems: 'baseline',
        gap: '6px',
        paddingTop: '12px',
        paddingBottom: '12px',
        paddingLeft: '14px',
        paddingRight: '14px',
        backgroundColor: '#F9FAFB',
        border: `1px solid ${colors.line}`,
        borderRadius: '12px',
      }}>
        <span style={{
          fontFamily: 'Gilroy', fontWeight: 700, fontSize: '24px', color: colors.muted,
        }}>$</span>
        <input
          type="text"
          inputMode="decimal"
          value={value}
          placeholder="0.00"
          onChange={onInput}
          style={{
            flex: 1,
            border: 'none',
            outline: 'none',
            background: 'transparent',
            fontFamily: 'Gilroy',
            fontWeight: 700,
            fontSize: '24px',
            color: colors.ink,
            fontVariantNumeric: 'tabular-nums',
            padding: 0,
            margin: 0,
            width: '100%',
            minWidth: 0,
          }}
        />
        {max != null ? (
          <button
            onClick={() => setValue(String(max.toFixed(2)))}
            style={{
              border: `1px solid ${colors.line}`,
              background: '#fff',
              borderRadius: '6px',
              padding: '4px 8px',
              cursor: 'pointer',
              fontFamily: 'Gilroy',
              fontWeight: 600,
              fontSize: '11px',
              color: colors.muted,
              flexShrink: 0,
            }}
          >MAX</button>
        ) : null}
      </div>
      <div style={{ display: 'flex', flexDirection: 'row', gap: '6px' }}>
        {QUICK_AMOUNTS.map((q) => (
          <button
            key={q}
            onClick={() => setValue(String(q.toFixed(2)))}
            style={{
              flex: 1,
              border: `1px solid ${colors.line}`,
              background: '#fff',
              borderRadius: '8px',
              padding: '6px 0',
              cursor: 'pointer',
              fontFamily: 'Gilroy',
              fontWeight: 600,
              fontSize: '12px',
              color: colors.muted,
            }}
          >${q.toLocaleString('en-US')}</button>
        ))}
      </div>
    </div>
  );
};

const Section = ({ label, children }) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
    <span style={{
      fontFamily: 'Inter',
      fontWeight: 500,
      fontSize: '11px',
      letterSpacing: '0.4px',
      color: colors.muted,
      textTransform: 'uppercase',
    }}>{label}</span>
    {children}
  </div>
);

const Arrow = () => (
  <div style={{
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: '4px',
    paddingBottom: '4px',
  }}>
    <ArrowDown color={colors.muted2}/>
  </div>
);

const CashFlowSheet = ({ mode, visible, onClose }) => {
  const [mounted, setMounted] = React.useState(false);
  const [shown, setShown] = React.useState(false);
  /* Cache the latest non-null mode locally. Without this, when the
     parent flips mode → null on close, the early-return below would
     unmount the sheet immediately and skip the close animation. By
     keeping `activeMode` populated through the close transition the
     form continues to render until `mounted` flips false. */
  const [activeMode, setActiveMode] = React.useState(mode);
  React.useEffect(() => { if (mode) setActiveMode(mode); }, [mode]);

  /* Form state. account is used for deposit (target) + withdraw (source).
     transfer uses fromId / toId. */
  const [amount, setAmount] = React.useState(() => {
    /* Voice tool open_cash_flow may pre-fill via window.__cashFlowAmount.
       Consume + clear so it doesn't leak into the next mount. */
    if (typeof window !== 'undefined' && window.__cashFlowAmount) {
      const v = window.__cashFlowAmount;
      window.__cashFlowAmount = '';
      return v;
    }
    return '';
  });
  const [account, setAccount] = React.useState('trading');
  const [fromId, setFromId] = React.useState('trading');
  const [toId, setToId] = React.useState('gold');

  const balances = window.useBalances();
  const { deposit, withdraw, transfer, addPendingWithdrawal } = window.useTradeMutators();

  /* Deposit demo: pressing Confirm shows a 5s spinner, then "fails"
     without moving any money. Triggers the global notification. */
  const [processing, setProcessing] = React.useState(false);
  React.useEffect(() => { if (visible) setProcessing(false); }, [visible, mode]);

  /* Reset form whenever the mode changes (or the sheet opens). The
     voice tool open_cash_flow may pre-fill via window.__cashFlowAmount;
     consume + clear here so the next open isn't sticky. */
  React.useEffect(() => {
    if (visible) {
      const preset = (typeof window !== 'undefined' && window.__cashFlowAmount) ? window.__cashFlowAmount : '';
      if (preset) window.__cashFlowAmount = '';
      setAmount(preset);
      setAccount('trading');
      setFromId('trading');
      setToId('gold');
    }
  }, [visible, mode]);

  /* Mount / shown / unmount choreography — same double-rAF trick as
     EquitiPlusModal so the open transition has a starting frame. */
  React.useEffect(() => {
    if (visible) {
      setMounted(true);
      let raf2;
      const raf1 = requestAnimationFrame(() => {
        raf2 = requestAnimationFrame(() => setShown(true));
      });
      return () => {
        cancelAnimationFrame(raf1);
        if (raf2) cancelAnimationFrame(raf2);
      };
    } else if (mounted) {
      setShown(false);
      const t = setTimeout(() => setMounted(false), ANIM_MS);
      return () => clearTimeout(t);
    }
  }, [visible]);

  /* Derive validation + handleConfirm BEFORE the visibility early-
     return so the bridge useEffect below stays at the top level
     (Rules of Hooks). When the sheet isn't mounted, activeMode is
     stale but harmless — the bridge methods just won't be useful. */
  const m = TITLES[activeMode || 'deposit'] || TITLES.deposit;
  const amt = parseFloat(amount);
  const validAmount = isFinite(amt) && amt > 0;

  /* Caps: deposit has no cap (card has infinite money in demo).
     Withdraw is capped to the source account's balance.
     Transfer is capped to fromId's balance, and from !== to. */
  let cap = null;
  if (activeMode === 'withdraw') cap = balances[account] || 0;
  else if (activeMode === 'transfer') cap = balances[fromId] || 0;

  const overCap = cap != null && validAmount && amt > cap;
  const sameAccount = activeMode === 'transfer' && fromId === toId;
  const canConfirm = validAmount && !overCap && !sameAccount;

  const handleConfirm = () => {
    if (!canConfirm || processing) return;
    if (activeMode === 'deposit') {
      /* Demo: spin for 5 seconds, then "fail" with no balance change.
         The global notification surfaces the explanation. */
      setProcessing(true);
      setTimeout(() => {
        setProcessing(false);
        if (window.showCashFlowNotification) window.showCashFlowNotification('deposit');
      }, 5000);
      return;
    }
    if (activeMode === 'withdraw') {
      /* Demo: withdrawal goes pending. Balance is NOT subtracted; the
         wallet's pending row reflects the request via the new
         pendingWithdrawals slice. The same notification surfaces the
         "payment provider delay" explanation. */
      addPendingWithdrawal(account, amt);
      onClose();
      if (window.showCashFlowNotification) window.showCashFlowNotification('withdraw');
      return;
    }
    if (activeMode === 'transfer') {
      transfer(fromId, toId, amt);
      onClose();
      if (window.showToast) {
        const label = `${ACCOUNT_LABEL[fromId]} → ${ACCOUNT_LABEL[toId]}`;
        window.showToast(`${m.toast} · ${fmtUSD(amt)} ${label}`, 'success');
      }
    }
  };

  /* Programmatic bridge — voice tool open_cash_flow(execute=true)
     calls these after the sheet has rendered: setAmount visibly,
     then confirm. Re-bound every render so closures stay fresh. */
  React.useEffect(() => {
    window.equiti = window.equiti || {};
    window.equiti.cashFlow = {
      setAmount: (v) => setAmount(String(v == null ? '' : v)),
      setAccount: (id) => setAccount(id),
      setTransferFrom: (id) => setFromId(id),
      setTransferTo: (id) => setToId(id),
      confirm: handleConfirm,
      canConfirm: () => mounted && !!activeMode && canConfirm && !processing,
      mode: () => activeMode,
    };
  });

  if (!mounted || !activeMode) return null;

  return (
    <div
      onClick={onClose}
      style={{
        position: 'absolute',
        inset: 0,
        background: 'rgba(14,20,32,0.55)',
        zIndex: 9000,
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'flex-end',
        opacity: shown ? 1 : 0,
        transition: `opacity ${ANIM_MS}ms ${EASE}`,
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          backgroundColor: '#fff',
          borderRadius: '24px 24px 0 0',
          maxHeight: '90%',
          display: 'flex',
          flexDirection: 'column',
          boxShadow: '0px -12px 40px rgba(14,20,32,0.24)',
          transform: shown ? 'translateY(0)' : 'translateY(100%)',
          transition: `transform ${ANIM_MS}ms ${EASE}`,
          overflow: 'hidden',
        }}
      >
        {/* Drag handle pill. */}
        <div style={{ display: 'flex', justifyContent: 'center', paddingTop: '8px', paddingBottom: '4px', flexShrink: 0 }}>
          <div style={{ width: '60px', height: '4px', borderRadius: '2px', backgroundColor: colors.line }}/>
        </div>

        {/* Header — title + close. */}
        <div style={{
          flexShrink: 0,
          paddingLeft: '20px',
          paddingRight: '20px',
          paddingTop: '8px',
          paddingBottom: '12px',
          display: 'flex',
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'space-between',
        }}>
          <span style={{
            fontFamily: 'Gilroy',
            fontWeight: 700,
            fontSize: '20px',
            color: colors.ink,
          }}>{m.title}</span>
          <button
            onClick={onClose}
            aria-label="Close"
            style={{
              border: 'none',
              background: colors.bg,
              padding: 0, margin: 0,
              cursor: 'pointer',
              width: '32px', height: '32px',
              borderRadius: '16px',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}
          >
            <CloseGlyph />
          </button>
        </div>

        {/* Scrollable form body. */}
        <div style={{
          flex: 1,
          overflowY: 'auto',
          WebkitOverflowScrolling: 'touch',
          paddingLeft: '20px',
          paddingRight: '20px',
          paddingTop: '4px',
          paddingBottom: '16px',
          display: 'flex',
          flexDirection: 'column',
          gap: '16px',
        }}>
          {activeMode === 'deposit' ? (
            <>
              <Section label="From">
                <CardPanel />
              </Section>
              <Arrow />
              <Section label="To">
                <AccountChips value={account} onChange={setAccount} />
              </Section>
            </>
          ) : null}

          {activeMode === 'withdraw' ? (
            <>
              <Section label="From">
                <AccountChips value={account} onChange={setAccount} />
              </Section>
              <Arrow />
              <Section label="To">
                <CardPanel />
              </Section>
            </>
          ) : null}

          {activeMode === 'transfer' ? (
            <>
              <Section label="From">
                <AccountChips value={fromId} onChange={setFromId} exclude={toId} />
              </Section>
              <Arrow />
              <Section label="To">
                <AccountChips value={toId} onChange={setToId} exclude={fromId} />
              </Section>
            </>
          ) : null}

          <Section label="Amount">
            <AmountField value={amount} setValue={setAmount} max={cap} />
            {overCap ? (
              <span style={{ fontFamily: 'Inter', fontSize: '12px', color: colors.red }}>
                Amount exceeds available balance ({fmtUSD(cap)}).
              </span>
            ) : null}
          </Section>
        </div>

        {/* Sticky CTA. paddingBottom = 24 + env(safe-area-inset-bottom)
            so the Confirm button stays above the iOS home indicator on PWA. */}
        <div style={{
          flexShrink: 0,
          paddingLeft: '20px',
          paddingRight: '20px',
          paddingTop: '12px',
          paddingBottom: 'calc(24px + env(safe-area-inset-bottom, 0px))',
          backgroundColor: '#fff',
          borderTop: '1px solid #F2F4F7',
        }}>
          <button
            onClick={handleConfirm}
            disabled={!canConfirm || processing}
            style={{
              width: '100%',
              height: '52px',
              border: 'none',
              borderRadius: '14px',
              background: processing ? colors.teal : (canConfirm ? colors.teal : '#D9DDE4'),
              cursor: (canConfirm && !processing) ? 'pointer' : 'not-allowed',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              gap: '10px',
              padding: 0,
              transition: 'background-color 200ms ease',
            }}
          >
            {processing ? (
              <React.Fragment>
                <Spinner color="#fff"/>
                <span style={{
                  fontFamily: 'Gilroy',
                  fontWeight: 600,
                  fontSize: '15px',
                  color: '#fff',
                }}>Processing…</span>
              </React.Fragment>
            ) : (
              <span style={{
                fontFamily: 'Gilroy',
                fontWeight: 600,
                fontSize: '15px',
                color: canConfirm ? '#fff' : colors.muted2,
              }}>{validAmount ? `${m.cta} · ${fmtUSD(amt)}` : m.cta}</span>
            )}
          </button>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { CashFlowSheet });
})();
