/* Stratiphy — "Find and transfer your ISAs" journey, in the Stratiphy app's own
   light visual language (white cards, violet/gold/green brand, app typography).
   Five steps:
   1. Connect      — log in to your ISA provider (Nortvest)
   2. Loading      — Open Banking → Authentication → Retrieving data
   3. Select       — pick which ISAs to transfer to Stratiphy
   4. Confirm      — review summary + electronic signature + sign
   5. Done         — transfer started
   Renders full-screen inside the host pane. Uses globals PI, StratDonut, gbp,
   STR_PURPLE, STR_PURPLE_DEEP, STR_PURPLE_SOFT, STR_GREEN, STR_INK, strIconBtn
   from stratiphy.jsx. Exports IsaTransferFlow to window. */

function gbpWhole(n) {
  return '£' + Math.round(n).toLocaleString('en-GB');
}

/* Normalise an ISA reference / account number into a tidy, readable format:
   uppercase, alphanumeric only, grouped into blocks of 4 (e.g. "AB12 3456 7890").
   Capped at 16 characters since provider references rarely run longer. */
function formatIsaRef(raw) {
  const clean = (raw || '').toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 16);
  return clean.replace(/(.{4})/g, '$1 ').trim();
}

/* Build the transferable ISA list from a selected provider's accounts.
   Prefer ISA accounts; fall back to all accounts if the provider has none. */
function isasFor(provider) {
  if (!provider) return [];
  const accts = provider.accounts && provider.accounts.length ? provider.accounts : [{ type: provider.accountType || 'Account', balance: provider.balance || 0 }];
  const isas = accts.filter((a) => /ISA/i.test(a.type));
  const list = isas.length ? isas : accts;
  return list.map((a, i) => ({ key: String(i), type: a.type, provider: provider.name, amount: a.balance || 0 }));
}

/* ---- shared light-flow primitives ---- */

function PurpleBtn({ children, onClick, disabled }) {
  return (
    <button onClick={onClick} disabled={disabled} style={{ width: '100%', height: 56, borderRadius: 1000, border: 'none', cursor: disabled ? 'default' : 'pointer', background: disabled ? 'var(--neutral-5)' : STR_PURPLE, color: disabled ? 'var(--neutral-8)' : '#fff', fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 17, transition: 'background 180ms cubic-bezier(0.2,0.7,0.2,1)' }}>{children}</button>);

}

function FlowHeader({ title, onBack, isClose, step }) {
  return (
    <div style={{ flexShrink: 0, padding: '58px 20px 14px', display: 'flex', alignItems: 'center', gap: 12, borderBottom: '1px solid var(--neutral-4)' }}>
      <button onClick={onBack} aria-label={isClose ? 'Close' : 'Back'} style={{ ...strIconBtn }}>
        {isClose ?
        <PI size={26} c={STR_INK} w={2.1}><path d="M6 6l12 12M18 6L6 18" /></PI> :
        <PI size={26} c={STR_INK} w={2.1}><path d="M15 5l-7 7 7 7" /></PI>}
      </button>
      <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 18, color: STR_INK }}>{title}</span>
      {step &&
      <span style={{ marginLeft: 'auto', fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 13, color: STR_PURPLE, background: STR_PURPLE_SOFT, borderRadius: 1000, padding: '5px 11px', whiteSpace: 'nowrap' }}>{step}</span>}
    </div>);

}

/* styled native select matching FIELD */
function SelectField({ value, onChange, options, placeholder }) {
  return (
    <div style={{ position: 'relative' }}>
      <select value={value} onChange={(e) => onChange(e.target.value)} style={{ ...FIELD, appearance: 'none', WebkitAppearance: 'none', paddingRight: 42, color: value ? '#16161D' : 'var(--neutral-7)', cursor: 'pointer' }}>
        <option value="" disabled>{placeholder}</option>
        {options.map((o) => <option key={o} value={o}>{o}</option>)}
      </select>
      <span style={{ position: 'absolute', right: 14, top: 0, height: 52, display: 'flex', alignItems: 'center', pointerEvents: 'none' }}>
        <PI size={20} c="var(--neutral-8)" w={2}><path d="M6 9l6 6 6-6" /></PI>
      </span>
    </div>);

}

/* mock account holder — what Stratiphy already knows about the user */
const USER = {
  title: 'Ms', first: 'Amelia', last: 'Hartley',
  dob: '14-03-1991', nationality: 'British', ni: 'QQ 12 34 56 C',
  street: '48 Lavender Hill', city: 'London', postcode: 'SW11 5RH',
  phone: '07700 900482', email: 'amelia.hartley@gmail.com'
};

const TITLES = ['Mr', 'Mrs', 'Ms', 'Miss', 'Mx', 'Dr'];
const ISA_TYPES_FROM = ['Stocks & Shares ISA', 'Cash ISA', 'Innovative Finance ISA', 'Lifetime ISA'];
const ISA_TYPES_TO = ['Stocks & Shares ISA', 'Innovative Finance ISA (IFISA)'];
const TRANSFER_TYPES = ['Full transfer', 'Partial transfer'];

function InsurelyNote() {
  return null;
}

function Check({ on, round }) {
  return (
    <span style={{ width: 24, height: 24, borderRadius: round ? '50%' : 7, border: on ? 'none' : '1.7px solid var(--neutral-6)', background: on ? STR_PURPLE : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, transition: 'background 160ms ease' }}>
      {on && <PI size={14} c="#fff" w={3}><path d="M5 12l4.5 4.5L19 7" /></PI>}
    </span>);

}

const FIELD = { width: '100%', boxSizing: 'border-box', height: 52, borderRadius: 12, border: '1px solid var(--neutral-5)', background: '#fff', padding: '0 16px', color: '#16161D', fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 16, outline: 'none' };
const LABEL = { display: 'block', fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 13.5, color: 'var(--neutral-9)', marginBottom: 8 };

/* ===================== 1 · PICK PROVIDER ===================== */

function PickProviderStep({ onClose, onSelect }) {
  const [q, setQ] = React.useState('');
  const all = (typeof PROVIDERS !== 'undefined' ? PROVIDERS : []);
  const list = all.filter((p) => p.name.toLowerCase().includes(q.toLowerCase()));
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Find your ISAs" onBack={onClose} isClose />

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 30, lineHeight: '35px', letterSpacing: '-0.02em', color: STR_INK, margin: 0 }}>Where do you hold<br />your ISAs?</h1>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '20px', color: 'var(--neutral-9)', margin: '10px 0 18px' }}>Choose your provider to securely find and transfer the ISAs you hold there.</p>

        <div style={{ height: 50, borderRadius: 12, border: '1px solid var(--neutral-5)', background: '#fff', display: 'flex', alignItems: 'center', gap: 10, padding: '0 16px' }}>
          <PI size={19} c="var(--neutral-8)" w={2}><circle cx="11" cy="11" r="7" /><path d="M20 20l-3.6-3.6" /></PI>
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search for your provider"
          style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 15.5, color: STR_INK }} />
        </div>

        <div style={{ marginTop: 16, background: '#fff', border: '1px solid var(--neutral-4)', borderRadius: 18, boxShadow: 'var(--elevation-default)', overflow: 'hidden' }}>
          {list.map((p, i) =>
          <button key={p.name} onClick={() => onSelect(p)} style={{ width: '100%', appearance: 'none', background: 'transparent', textAlign: 'left', border: 'none', borderBottom: i < list.length - 1 ? '1px solid var(--neutral-4)' : 'none', padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 14, cursor: 'pointer' }}>
              <Logo p={p} size={40} />
              <span style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 3 }}>
                <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 16.5, color: STR_INK, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</span>
              </span>
              <PI size={20} c={STR_PURPLE} w={2}><path d="M9 6l6 6-6 6" /></PI>
            </button>
          )}
          {list.length === 0 &&
          <div style={{ padding: '24px 16px', fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 15, color: 'var(--neutral-9)' }}>No providers found.</div>}
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}><InsurelyNote /></div>
    </div>);

}

/* ===================== 2 · CONNECT ===================== */

function ConnectStep({ provider, onBack, onConnect }) {
  const [show, setShow] = React.useState(false);
  const [agree, setAgree] = React.useState(true);
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Connect provider" onBack={onBack} />

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 13, marginBottom: 8 }}>
          <Logo p={provider} size={46} />
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 22, color: STR_INK }}>{provider.name}</span>
        </div>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '21px', color: 'var(--neutral-9)', margin: '14px 0 24px' }}>
          Log in to {provider.name} to securely retrieve the ISAs you hold there. Stratiphy never sees your login details.
        </p>

        <label style={LABEL}>User ID</label>
        <input style={FIELD} />

        <label style={{ ...LABEL, marginTop: 18 }}>Password</label>
        <div style={{ position: 'relative' }}>
          <input type={show ? 'text' : 'password'} style={{ ...FIELD, paddingRight: 46 }} />
          <button onClick={() => setShow((s) => !s)} aria-label="Show password" style={{ position: 'absolute', right: 12, top: 0, height: 52, appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center' }}>
            <PI size={21} c={STR_PURPLE} w={1.9}><path d="M6 9l6 6 6-6" /></PI>
          </button>
        </div>

        <button onClick={() => setAgree((a) => !a)} style={{ appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 11, padding: 0, marginTop: 22 }}>
          <Check on={agree} />
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14, color: 'var(--neutral-10)', textAlign: 'left' }}>I have read and accept the <span style={{ color: STR_PURPLE, textDecoration: 'underline' }}>Terms of use</span></span>
        </button>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 22px 16px' }}>
        <PurpleBtn onClick={onConnect} disabled={!agree}>Connect to {provider.name}</PurpleBtn>
        <div style={{ height: 14 }} />
      </div>
    </div>);

}

/* ===================== 3 · LOADING ===================== */

function LoadingStep({ provider, onBack, onDone }) {
  const steps = [
  { label: 'Connecting', kind: 'link', dur: 1300 },
  { label: 'Authentication', kind: 'shield', dur: 1200 },
  { label: 'Retrieving your data', kind: 'search', dur: 1600 }];

  const [active, setActive] = React.useState(0);
  const [fill, setFill] = React.useState([0, 0, 0]);

  React.useEffect(() => {
    let cancelled = false;
    const wait = (ms) => new Promise((r) => setTimeout(r, ms));
    (async () => {
      for (let i = 0; i < steps.length; i++) {
        if (cancelled) return;
        setActive(i);
        await wait(80);
        if (cancelled) return;
        setFill((f) => {const n = [...f];n[i] = 100;return n;});
        await wait(steps[i].dur);
      }
      await wait(420);
      if (!cancelled) onDone();
    })();
    return () => {cancelled = true;};
  }, []);

  const icon = (kind, c) => {
    if (kind === 'link') return <PI size={16} c={c} w={2.2}><path d="M9 14a4 4 0 0 0 5.7 0l2.3-2.3a4 4 0 0 0-5.7-5.7L10 7" /><path d="M15 10a4 4 0 0 0-5.7 0L7 12.3a4 4 0 0 0 5.7 5.7L14 17" /></PI>;
    if (kind === 'shield') return <PI size={16} c={c} w={2.2}><path d="M12 3l7 3v5c0 4.4-3 7.4-7 8.8-4-1.4-7-4.4-7-8.8V6z" /><path d="M9 12l2 2 4-4" /></PI>;
    return <PI size={16} c={c} w={2.2}><circle cx="11" cy="11" r="6.5" /><path d="M20 20l-3.5-3.5" /></PI>;
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title={`Connecting to ${provider.name}`} onBack={onBack} />

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {steps.map((s, i) => {
            const done = i < active;
            const reached = i <= active;
            return (
              <div key={i} style={{ background: '#fff', border: '1px solid var(--neutral-4)', borderRadius: 16, padding: '15px 16px', opacity: reached ? 1 : 0.45, transition: 'opacity 300ms ease' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 13 }}>
                  <span style={{ width: 32, height: 32, borderRadius: '50%', flexShrink: 0, background: done ? STR_GREEN : STR_PURPLE_SOFT, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    {done ? <PI size={16} c="#fff" w={3}><path d="M5 12l4.5 4.5L19 7" /></PI> : icon(s.kind, STR_PURPLE)}
                  </span>
                  <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 15.5, color: STR_INK }}>{s.label}</span>
                </div>
                <div style={{ marginTop: 13, height: 6, borderRadius: 100, background: 'var(--neutral-3)', overflow: 'hidden' }}>
                  <div style={{ height: '100%', borderRadius: 100, background: done ? STR_GREEN : STR_PURPLE, width: fill[i] + '%', transition: `width ${s.dur}ms linear` }} />
                </div>
              </div>);

          })}
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}><InsurelyNote /></div>
    </div>);

}

/* ===================== 3 · SELECT ===================== */

function SelectStep({ provider, onBack, selected, setSelected, onContinue }) {
  const isas = isasFor(provider);
  // single-select: choosing one account clears any other selection
  const toggle = (k) => setSelected((s) => (s[k] ? {} : { [k]: true }));
  const count = Object.values(selected).filter(Boolean).length;
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Select ISAs" onBack={onBack} />

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, background: STR_GREEN_SOFT, borderRadius: 1000, padding: '6px 13px' }}>
          <PI size={15} c={STR_GREEN} w={2.6}><path d="M5 12l4.5 4.5L19 7" /></PI>
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 13.5, color: '#0E8C53' }}>Connected to {provider.name}</span>
        </span>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 30, lineHeight: '35px', letterSpacing: '-0.02em', color: STR_INK, margin: '16px 0 0' }}>Which ISAs would you<br />like to transfer?</h1>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '20px', color: 'var(--neutral-9)', margin: '10px 0 18px' }}>We found {isas.length} account{isas.length !== 1 ? 's' : ''} at {provider.name}. Choose which to move to Stratiphy.</p>

        <div style={{ background: '#fff', border: '1px solid var(--neutral-4)', borderRadius: 18, boxShadow: 'var(--elevation-default)', overflow: 'hidden' }}>
          {isas.map((isa, i) => {
            const on = !!selected[isa.key];
            return (
              <button key={isa.key} onClick={() => toggle(isa.key)} style={{ width: '100%', appearance: 'none', border: 'none', background: on ? STR_PURPLE_SOFT : '#fff', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 13, padding: '16px', borderBottom: i < isas.length - 1 ? '1px solid var(--neutral-4)' : 'none', transition: 'background 160ms ease' }}>
                <Logo p={provider} size={38} />
                <span style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 3, textAlign: 'left' }}>
                  <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 16, color: STR_INK }}>{isa.type}</span>
                  <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13, color: 'var(--neutral-9)' }}>{isa.provider} · <span style={{ fontWeight: 600, color: STR_INK, fontVariantNumeric: 'tabular-nums' }}>{gbpWhole(isa.amount)}</span></span>
                </span>
                <Check on={on} round />
              </button>);

          })}
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onContinue} disabled={count === 0}>{count > 0 ? `Continue with ${count} ISA${count !== 1 ? 's' : ''}` : 'Select an ISA'}</PurpleBtn>
      </div>
    </div>);

}

/* ===================== 4 · CONFIRM ===================== */

function ConfirmStep({ provider, onBack, selected, onSign }) {
  const [sig, setSig] = React.useState('');
  const [agree, setAgree] = React.useState(false);
  const chosen = isasFor(provider).filter((i) => selected[i.key]);
  const total = chosen.reduce((s, i) => s + i.amount, 0);
  const ready = sig.trim().length > 1 && agree;
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Confirm transfer" onBack={onBack} />

      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 22px 16px' }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 30, lineHeight: '36px', letterSpacing: '-0.02em', color: STR_INK, margin: 0 }}>Review and sign</h1>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '20px', color: 'var(--neutral-9)', margin: '10px 0 18px' }}>These ISAs will move to your Stratiphy account. Your existing providers stay open until the transfer lands.</p>

        <div style={{ background: '#fff', border: '1px solid var(--neutral-4)', borderRadius: 18, boxShadow: 'var(--elevation-default)', padding: '6px 16px' }}>
          {chosen.map((i, idx) =>
          <div key={i.key} style={{ display: 'flex', alignItems: 'center', gap: 12, justifyContent: 'space-between', padding: '14px 0', borderBottom: idx < chosen.length - 1 ? '1px solid var(--neutral-4)' : 'none' }}>
              <span style={{ display: 'flex', alignItems: 'center', gap: 12, minWidth: 0 }}>
                <Logo p={provider} size={34} />
                <span style={{ minWidth: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
                  <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 15.5, color: STR_INK, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{i.type}</span>
                  <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13, color: 'var(--neutral-9)' }}>{i.provider}</span>
                </span>
              </span>
              <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 15.5, color: STR_INK, flexShrink: 0, fontVariantNumeric: 'tabular-nums' }}>{gbpWhole(i.amount)}</span>
            </div>
          )}
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '15px 0', borderTop: '1px solid var(--neutral-4)' }}>
            <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 16, color: STR_INK }}>Total transferring</span>
            <span style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 19, color: STR_PURPLE, fontVariantNumeric: 'tabular-nums' }}>{gbpWhole(total)}</span>
          </div>
        </div>

        <label style={{ ...LABEL, marginTop: 20 }}>Electronic signature</label>
        <div style={{ position: 'relative' }}>
          <span style={{ position: 'absolute', left: 16, top: 21, display: 'flex', alignItems: 'center', gap: 8, pointerEvents: 'none' }}>
            {!sig &&
            <React.Fragment>
                <PI size={17} c="var(--neutral-7)" w={1.9}><path d="M12 20h9" /><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z" /></PI>
                <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, color: 'var(--neutral-7)' }}>Sign your name</span>
              </React.Fragment>}
          </span>
          <input value={sig} onChange={(e) => setSig(e.target.value)} aria-label="Electronic signature"
          style={{ width: '100%', boxSizing: 'border-box', height: 66, borderRadius: 14, border: '1px solid var(--neutral-5)', background: '#fff', padding: '0 16px', color: STR_INK, outline: 'none', fontFamily: '"Snell Roundhand","Brush Script MT",cursive', fontSize: 27, fontWeight: 600 }} />
        </div>

        <button onClick={() => setAgree((a) => !a)} style={{ appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'flex-start', gap: 11, padding: 0, marginTop: 18 }}>
          <Check on={agree} />
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13.5, lineHeight: '19px', color: 'var(--neutral-10)', textAlign: 'left' }}>I authorise the transfer of these accounts and confirm I have read the <span style={{ color: STR_PURPLE, textDecoration: 'underline' }}>terms and conditions</span>.</span>
        </button>

        <div style={{ marginTop: 18, display: 'flex', alignItems: 'flex-start', gap: 10, background: STR_PURPLE_SOFT, borderRadius: 14, padding: '14px 16px' }}>
          <PI size={19} c={STR_PURPLE} w={2}><circle cx="12" cy="12" r="9" /><path d="M12 16v-4M12 8h.01" /></PI>
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13.5, lineHeight: '19px', color: STR_INK }}>Transfers are handled provider-to-provider and usually complete in about 14 minutes. You keep your full ISA allowance.</span>
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onSign} disabled={!ready}>Sign and confirm</PurpleBtn>
      </div>
    </div>);

}

/* ===================== 5 · DONE ===================== */

function DoneStep({ provider, selected, onClose }) {
  const chosen = isasFor(provider).filter((i) => selected[i.key]);
  const total = chosen.reduce((s, i) => s + i.amount, 0);
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '0 32px' }}>
        <span style={{ width: 80, height: 80, borderRadius: '50%', background: STR_GREEN_SOFT, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <span style={{ width: 56, height: 56, borderRadius: '50%', background: STR_GREEN, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <PI size={31} c="#fff" w={3}><path d="M5 12l4.5 4.5L19 7" /></PI>
          </span>
        </span>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 32, letterSpacing: '-0.02em', color: STR_INK, margin: '24px 0 0' }}>Transfer started</h1>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 15, lineHeight: '22px', color: 'var(--neutral-9)', margin: '12px 0 0', maxWidth: 300 }}>
          We're moving {gbpWhole(total)} across {chosen.length} ISA{chosen.length !== 1 ? 's' : ''} to Stratiphy. We'll notify you when it lands — usually about 14 minutes.
        </p>
      </div>
      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onClose}>Back to portfolio</PurpleBtn>
      </div>
    </div>);

}

/* ===================== TRANSFER FORM (from Stratiphy ISA Transfer Form) ===================== */

const FieldBlock = ({ label, children, optional }) => (
  <div style={{ marginTop: 16 }}>
    <label style={LABEL}>{label}{optional && <span style={{ fontWeight: 500, color: 'var(--neutral-7)' }}> (optional)</span>}</label>
    {children}
  </div>);


/* Form step 1 of 4 — Your details */
function DetailsStep({ form, up, onBack, onContinue }) {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Your details" onBack={onBack} step="Step 1 of 4" />
      <div style={{ flex: 1, overflowY: 'auto', padding: '22px 22px 16px' }}>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '20px', color: 'var(--neutral-9)', margin: '0 0 4px' }}>We've filled these in from your Stratiphy account. Check they match your current provider's records.</p>

        <FieldBlock label="Title"><SelectField value={form.title} onChange={(v) => up({ title: v })} options={TITLES} placeholder="Please select" /></FieldBlock>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flex: 1 }}><FieldBlock label="First name"><input value={form.first} onChange={(e) => up({ first: e.target.value })} style={FIELD} /></FieldBlock></div>
          <div style={{ flex: 1 }}><FieldBlock label="Last name"><input value={form.last} onChange={(e) => up({ last: e.target.value })} style={FIELD} /></FieldBlock></div>
        </div>
        <FieldBlock label="Date of birth"><input value={form.dob} onChange={(e) => up({ dob: e.target.value })} placeholder="DD-MM-YYYY" style={FIELD} /></FieldBlock>
        <FieldBlock label="Nationality"><input value={form.nationality} onChange={(e) => up({ nationality: e.target.value })} style={FIELD} /></FieldBlock>
        <FieldBlock label="National Insurance number"><input value={form.ni} onChange={(e) => up({ ni: e.target.value })} style={FIELD} /></FieldBlock>
        <FieldBlock label="Address"><input value={form.street} onChange={(e) => up({ street: e.target.value })} placeholder="Street address" style={FIELD} /></FieldBlock>
        <div style={{ display: 'flex', gap: 12, marginTop: 12 }}>
          <div style={{ flex: 1.4 }}><input value={form.city} onChange={(e) => up({ city: e.target.value })} placeholder="City" style={FIELD} /></div>
          <div style={{ flex: 1 }}><input value={form.postcode} onChange={(e) => up({ postcode: e.target.value })} placeholder="Post code" style={FIELD} /></div>
        </div>
        <FieldBlock label="Phone number"><input value={form.phone} onChange={(e) => up({ phone: e.target.value })} placeholder="07xxx xxxxxx" style={FIELD} /></FieldBlock>
        <FieldBlock label="Email"><input value={form.email} onChange={(e) => up({ email: e.target.value })} placeholder="example@example.com" style={FIELD} /></FieldBlock>
      </div>
      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onContinue} disabled={!form.first || !form.last || !form.email}>Continue</PurpleBtn>
      </div>
    </div>);

}

/* Form step 2 of 4 — Transfer details (sections 2, 3, 4) */
function TransferDetailsStep({ provider, form, up, chosen, onBack, onContinue }) {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Transfer details" onBack={onBack} step="Step 2 of 4" />
      <div style={{ flex: 1, overflowY: 'auto', padding: '22px 22px 16px' }}>
        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, lineHeight: '20px', color: 'var(--neutral-9)', margin: '0 0 4px' }}>Details of the ISA you're transferring from, pre-filled from {provider.name}.</p>

        <FieldBlock label="Current ISA provider"><input value={form.fromProvider} onChange={(e) => up({ fromProvider: e.target.value })} style={FIELD} /></FieldBlock>
        <FieldBlock label="ISA reference / account number" optional><input value={form.accountNumber} onChange={(e) => up({ accountNumber: formatIsaRef(e.target.value) })} placeholder="e.g. AB12 3456 7890" inputMode="latin" autoCapitalize="characters" style={FIELD} /></FieldBlock>
        <FieldBlock label="Approximate transfer value"><input value={form.value} onChange={(e) => up({ value: e.target.value })} style={FIELD} /></FieldBlock>
        <FieldBlock label="ISA type transferring FROM"><SelectField value={form.isaFrom} onChange={(v) => up({ isaFrom: v })} options={ISA_TYPES_FROM} placeholder="Please select" /></FieldBlock>
        <FieldBlock label="ISA type transferring TO"><SelectField value={form.isaTo} onChange={(v) => up({ isaTo: v })} options={ISA_TYPES_TO} placeholder="Please select" /></FieldBlock>
        <FieldBlock label="Transfer type"><SelectField value={form.transferType} onChange={(v) => up({ transferType: v })} options={TRANSFER_TYPES} placeholder="Please select" /></FieldBlock>
      </div>
      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onContinue} disabled={!form.fromProvider || !form.value || !form.isaFrom || !form.isaTo || !form.transferType}>Continue</PurpleBtn>
      </div>
    </div>);

}

/* Form step 3 of 4 — Transfer method & important information (sections 5, 6) */
function MethodStep({ form, up, onBack, onContinue }) {
  const partial = form.transferType === 'Partial transfer';
  const risks = [
  'Transfers may take several weeks to complete',
  'Your investments may be out of the market during the transfer',
  'The value of your investments may change during this time',
  'Income payments or interest may be affected',
  'Some investments (particularly within IFISAs) may take longer to realise or may not be transferable in-specie'];

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Transfer method" onBack={onBack} step="Step 3 of 4" />
      <div style={{ flex: 1, overflowY: 'auto', padding: '22px 22px 16px' }}>
        <div style={{ background: STR_PURPLE_SOFT, borderRadius: 16, padding: '16px 18px' }}>
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 15.5, color: STR_INK }}>Transfers are made as cash</span>
          <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13.5, lineHeight: '19px', color: 'var(--neutral-10)', margin: '6px 0 0' }}>Your existing holdings will be sold by your current provider and the proceeds transferred as cash to your Stratiphy ISA.</p>
        </div>

        {partial &&
        <FieldBlock label="Investments to sell for this partial transfer">
            <textarea value={form.partialList} onChange={(e) => up({ partialList: e.target.value })} placeholder="List any investments you'd like sold to generate funds" rows={3}
          style={{ ...FIELD, height: 'auto', minHeight: 88, padding: '14px 16px', lineHeight: '21px', resize: 'none' }} />
          </FieldBlock>}

        <div style={{ marginTop: 22, fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 16, color: STR_INK }}>Important information</div>
        <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 12 }}>
          {risks.map((r, i) =>
          <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 11 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: STR_PURPLE, flexShrink: 0, marginTop: 8 }} />
              <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14, lineHeight: '20px', color: 'var(--neutral-10)' }}>{r}</span>
            </div>
          )}
        </div>

        <button onClick={() => up({ ackMethod: !form.ackMethod })} style={{ appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'flex-start', gap: 11, padding: 0, marginTop: 22 }}>
          <Check on={form.ackMethod} />
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13.5, lineHeight: '19px', color: 'var(--neutral-10)', textAlign: 'left' }}>I understand how the transfer works and the risks above.</span>
        </button>
      </div>
      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onContinue} disabled={!form.ackMethod}>Continue</PurpleBtn>
      </div>
    </div>);

}

/* Form step 4 of 4 — Declaration & signature (section 7) */
function DeclarationStep({ form, up, onBack, onSubmit }) {
  const points = [
  "I've read and agree to Stratiphy's ISA Terms & Conditions, Key Features Documents and relevant investment disclosures.",
  'I authorise my current ISA provider to transfer my ISA to Stratiphy and to provide any information required to complete it.',
  'I am the beneficial owner of the assets and cash being transferred, and the information provided is accurate to the best of my knowledge.'];

  const ready = form.agreeDeclare && form.sig.trim().length > 1 && form.fullName.trim().length > 1;
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#fafafa' }}>
      <FlowHeader title="Declaration" onBack={onBack} step="Step 4 of 4" />
      <div style={{ flex: 1, overflowY: 'auto', padding: '22px 22px 16px' }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 28, lineHeight: '34px', letterSpacing: '-0.02em', color: STR_INK, margin: 0 }}>Declaration and<br />authorisation</h1>

        <div style={{ marginTop: 16, background: '#fff', border: '1px solid var(--neutral-4)', borderRadius: 16, padding: '4px 16px' }}>
          {points.map((p, i) =>
          <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 11, padding: '13px 0', borderBottom: i < points.length - 1 ? '1px solid var(--neutral-4)' : 'none' }}>
              <PI size={18} c={STR_GREEN} w={2.4}><path d="M5 12l4.5 4.5L19 7" /></PI>
              <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 13.5, lineHeight: '19px', color: 'var(--neutral-10)' }}>{p}</span>
            </div>
          )}
        </div>

        <button onClick={() => up({ agreeDeclare: !form.agreeDeclare })} style={{ appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 11, padding: 0, marginTop: 16 }}>
          <Check on={form.agreeDeclare} />
          <span style={{ fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: 14, color: STR_INK, textAlign: 'left' }}>I confirm and agree to all of the above</span>
        </button>

        <label style={{ ...LABEL, marginTop: 22 }}>Signature</label>
        <div style={{ position: 'relative' }}>
          <span style={{ position: 'absolute', left: 16, top: 23, display: 'flex', alignItems: 'center', gap: 8, pointerEvents: 'none' }}>
            {!form.sig &&
            <React.Fragment>
                <PI size={17} c="var(--neutral-7)" w={1.9}><path d="M12 20h9" /><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z" /></PI>
                <span style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 14.5, color: 'var(--neutral-7)' }}>Sign your name</span>
              </React.Fragment>}
          </span>
          <input value={form.sig} onChange={(e) => up({ sig: e.target.value })} aria-label="Signature"
          style={{ width: '100%', boxSizing: 'border-box', height: 70, borderRadius: 14, border: '1px solid var(--neutral-5)', background: '#fff', padding: '0 16px', color: STR_INK, outline: 'none', fontFamily: '"Snell Roundhand","Brush Script MT",cursive', fontSize: 28, fontWeight: 600 }} />
        </div>

        <FieldBlock label="Full name (BLOCK CAPITALS)"><input value={form.fullName} onChange={(e) => up({ fullName: e.target.value.toUpperCase() })} style={{ ...FIELD, letterSpacing: '0.5px' }} /></FieldBlock>
        <FieldBlock label="Date"><input value={form.date} onChange={(e) => up({ date: e.target.value })} placeholder="DD-MM-YYYY" style={FIELD} /></FieldBlock>

        <p style={{ fontFamily: 'var(--font-body)', fontWeight: 500, fontSize: 11.5, lineHeight: '17px', color: 'var(--neutral-8)', marginTop: 20 }}>
          Stratiphy Limited is authorised and regulated by the Financial Conduct Authority (FRN: 976267), registered in England and Wales (No. 12510853), registered office 86–90 Paul Street, London, EC2A 4NE. When you invest, your capital is at risk.
        </p>
      </div>
      <div style={{ flexShrink: 0, padding: '12px 22px 26px' }}>
        <PurpleBtn onClick={onSubmit} disabled={!ready}>Submit transfer</PurpleBtn>
      </div>
    </div>);

}

/* ===================== FLOW CONTROLLER ===================== */

function IsaTransferFlow({ onClose, onComplete }) {
  const [step, setStep] = React.useState('pick');
  const [provider, setProvider] = React.useState(null);
  const [selected, setSelected] = React.useState({});
  const [form, setForm] = React.useState(null);
  const up = (patch) => setForm((f) => ({ ...f, ...patch }));

  const today = new Date().toLocaleDateString('en-GB').replace(/\//g, '-');

  const choose = (p) => {
    setProvider(p);
    // single-select: pre-select just the first account; the user can switch on the Select step
    const sel = {};
    const isas = isasFor(p);
    if (isas[0]) sel[isas[0].key] = true;
    setSelected(sel);
    setStep('connect');
  };

  // when leaving the select step, seed the form from what we know
  const toForm = () => {
    const chosenIsas = isasFor(provider).filter((i) => selected[i.key]);
    const total = chosenIsas.reduce((s, i) => s + i.amount, 0);
    const firstType = chosenIsas[0] && ISA_TYPES_FROM.find((t) => chosenIsas[0].type.includes(t.split(' ')[0])) || '';
    setForm({
      ...USER,
      fromProvider: provider.name,
      accountNumber: formatIsaRef('GB29' + (provider.name || '').replace(/[^A-Za-z0-9]/g, '').toUpperCase().slice(0, 4).padEnd(4, 'X') + '01234567'),
      value: gbpWhole(total),
      isaFrom: firstType || 'Stocks & Shares ISA',
      isaTo: 'Stocks & Shares ISA',
      transferType: 'Full transfer',
      partialList: '',
      ackMethod: false,
      agreeDeclare: false,
      sig: '',
      fullName: (USER.first + ' ' + USER.last).toUpperCase(),
      date: today
    });
    setStep('details');
  };

  const chosen = provider ? isasFor(provider).filter((i) => selected[i.key]) : [];

  const submit = () => {
    const total = chosen.reduce((s, i) => s + i.amount, 0);
    onComplete && onComplete({
      name: provider.name, logo: provider.logo, color: provider.color, mono: provider.mono,
      total, count: chosen.length, startedAt: Date.now()
    });
    setStep('done');
  };

  return (
    <div style={{ position: 'relative', height: '100%', background: '#fafafa', overflow: 'hidden' }}>
      {step === 'pick' && <PickProviderStep onClose={onClose} onSelect={choose} />}
      {step === 'connect' && <ConnectStep provider={provider} onBack={() => setStep('pick')} onConnect={() => setStep('loading')} />}
      {step === 'loading' && <LoadingStep provider={provider} onBack={() => setStep('connect')} onDone={() => setStep('select')} />}
      {step === 'select' && <SelectStep provider={provider} onBack={() => setStep('pick')} selected={selected} setSelected={setSelected} onContinue={toForm} />}
      {step === 'details' && <DetailsStep form={form} up={up} onBack={() => setStep('select')} onContinue={() => setStep('transfer')} />}
      {step === 'transfer' && <TransferDetailsStep provider={provider} form={form} up={up} chosen={chosen} onBack={() => setStep('details')} onContinue={() => setStep('method')} />}
      {step === 'method' && <MethodStep form={form} up={up} onBack={() => setStep('transfer')} onContinue={() => setStep('declaration')} />}
      {step === 'declaration' && <DeclarationStep form={form} up={up} onBack={() => setStep('method')} onSubmit={submit} />}
      {step === 'done' && <DoneStep provider={provider} selected={selected} onClose={onClose} />}
    </div>);

}

Object.assign(window, { IsaTransferFlow });
