// Settings — mirrors apps/web/src/app/(dashboard)/settings/page.tsx.
// App config (re-run thresholds, email alerts) + authorized users CRUD.

window.Settings = function Settings({ session, isElevated }) {
  const { useState, useEffect } = React;
  const settings = window.useApi(() => window.EQ_API.getSettings(), []);
  const users = window.useApi(() => window.EQ_API.getUsers(), []);
  const [draft, setDraft] = useState(null);
  const [saving, setSaving] = useState(false);
  const [savedAt, setSavedAt] = useState(null);
  const [saveError, setSaveError] = useState(null);

  useEffect(() => {
    if (settings.data && draft === null) setDraft(settings.data);
  }, [settings.data, draft]);

  const save = async () => {
    if (!draft) return;
    setSaving(true); setSaveError(null);
    try {
      await window.EQ_API.updateSettings(draft);
      setSavedAt(Date.now());
      settings.reload();
    } catch (e) { setSaveError(e.message); }
    finally { setSaving(false); }
  };

  return (
    <div>
      <window.TopBar title="Settings"/>
      <div style={{ padding: '24px 32px', display: 'flex', flexDirection: 'column', gap: 16 }}>
        {settings.error && <window.ErrorBanner error={settings.error} onRetry={settings.reload}/>}
        {settings.loading && <div style={{ color: 'var(--ink-500)', fontSize: 12.5 }}>Loading…</div>}

        {draft && (
          <Card title="Re-run & notifications">
            {saveError && <window.ErrorBanner error={{ message: saveError }}/>}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
              <NumField label="Re-run after (days)"
                value={draft.rerun_days}
                onChange={v => setDraft({ ...draft, rerun_days: v })}/>
              <NumField label="Price change threshold (%)"
                value={draft.price_change_threshold_pct ?? draft.price_change_threshold}
                onChange={v => setDraft({ ...draft, price_change_threshold_pct: v })}/>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 6 }}>
              <EmailChannel
                title="BUY signal emails"
                description="Sent when an analysis returns a BUY decision."
                toggleLabel="Auto-send BUY emails"
                toggle={!!draft.email_on_buy}
                onToggle={v => setDraft({ ...draft, email_on_buy: v })}
                recipients={draft.email_recipients_buy || draft.email_recipients || []}
                onRecipients={v => setDraft({ ...draft, email_recipients_buy: v })}/>
              <EmailChannel
                title="PASS signal emails"
                description="Sent when an analysis returns a PASS decision."
                toggleLabel="Auto-send PASS emails"
                toggle={!!draft.email_on_pass}
                onToggle={v => setDraft({ ...draft, email_on_pass: v })}
                recipients={draft.email_recipients_pass || draft.email_recipients || []}
                onRecipients={v => setDraft({ ...draft, email_recipients_pass: v })}/>
              <EmailChannel
                title="Approval recipients"
                description="Always added to BUY emails that carry an approval token, even if not on the BUY list above."
                toggleLabel="Include approvers on BUY emails with pending approvals"
                toggle={draft.email_on_approvals !== false}
                onToggle={v => setDraft({ ...draft, email_on_approvals: v })}
                recipients={draft.email_recipients_approvals || draft.email_recipients || []}
                onRecipients={v => setDraft({ ...draft, email_recipients_approvals: v })}/>
            </div>
            <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginTop: 10 }}>
              <button disabled={saving} onClick={save} style={{
                padding: '8px 16px', fontSize: 12.5, fontWeight: 500,
                background: 'var(--ink-900)', color: 'white', borderRadius: 7, border: 'none',
                cursor: saving ? 'default' : 'pointer', opacity: saving ? 0.6 : 1, fontFamily: 'inherit'
              }}>{saving ? 'Saving…' : 'Save'}</button>
              {savedAt && <span style={{ fontSize: 11.5, color: 'var(--ink-500)' }}>Saved {window.formatRelative(new Date(savedAt).toISOString())}</span>}
            </div>
          </Card>
        )}

        <Card title="Authorized users">
          <UsersPanel users={users} session={session} isElevated={isElevated}/>
        </Card>
      </div>
    </div>
  );
};

function UsersPanel({ users, session, isElevated }) {
  const { useState } = React;
  const [email, setEmail] = useState('');
  const [name, setName] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(null);

  // Only elevated users can add/remove users (frontend cosmetic — backend
  // enforces via require_elevated on POST/DELETE /api/users endpoints)
  const canManage = isElevated === true
    ? true
    : (window.EQ_IS_AUTHORIZED ? window.EQ_IS_AUTHORIZED(session) : false);

  const add = async (e) => {
    e.preventDefault();
    const body = { email: email.trim().toLowerCase() };
    if (name.trim()) body.display_name = name.trim();
    if (!body.email) return;
    setBusy(true); setError(null);
    try {
      await window.EQ_API.addUser(body);
      setEmail(''); setName('');
      users.reload();
    } catch (e) { setError(e.message); }
    finally { setBusy(false); }
  };

  const remove = async (id) => {
    if (!confirm('Remove this user?')) return;
    setBusy(true); setError(null);
    try { await window.EQ_API.removeUser(id); users.reload(); }
    catch (e) { setError(e.message); }
    finally { setBusy(false); }
  };

  // Promote/demote — toggles authorized_users.is_elevated. Admins gain
  // access to Run Analysis, Cancel, Approve/Reject, Add/Remove user, and
  // the Corporate Development tab.
  const toggleAdmin = async (u) => {
    const next = !u.is_elevated;
    const verb = next ? 'Promote' : 'Demote';
    const consequence = next
      ? 'They will gain admin powers (run analyses, approve, manage users).'
      : 'They will lose admin powers immediately.';
    if (!confirm(`${verb} ${u.email}?\n\n${consequence}`)) return;
    setBusy(true); setError(null);
    try {
      await window.EQ_API.updateUser(u.id, { is_elevated: next });
      users.reload();
    } catch (e) { setError(e.message); }
    finally { setBusy(false); }
  };

  const rows = users.data?.data || [];

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {error && <window.ErrorBanner error={{ message: error }}/>}
      <form onSubmit={(e) => { if (canManage) add(e); else e.preventDefault(); }}
            style={{ display: 'flex', gap: 6 }}>
        <input value={email} onChange={e => setEmail(e.target.value)} placeholder="user@onni.com" type="email"
          disabled={!canManage}
          style={{ flex: 2, padding: '8px 12px', fontSize: 12.5, background: 'var(--ink-100)', border: '1px solid var(--ink-200)', borderRadius: 7, outline: 'none', color: 'var(--ink-900)', fontFamily: 'var(--font-mono)', opacity: !canManage ? 0.55 : 1, cursor: !canManage ? 'not-allowed' : 'text' }}/>
        <input value={name} onChange={e => setName(e.target.value)} placeholder="Display name (optional)"
          disabled={!canManage}
          style={{ flex: 1, padding: '8px 12px', fontSize: 12.5, background: 'var(--ink-100)', border: '1px solid var(--ink-200)', borderRadius: 7, outline: 'none', color: 'var(--ink-900)', fontFamily: 'inherit', opacity: !canManage ? 0.55 : 1, cursor: !canManage ? 'not-allowed' : 'text' }}/>
        <button type="submit" disabled={busy || !email.trim() || !canManage}
          title={!canManage ? 'Restricted — only admins can add users.' : 'Add user'}
          style={{
            padding: '8px 14px', fontSize: 12.5, fontWeight: 500,
            background: !canManage ? 'var(--ink-300)' : 'var(--ink-900)',
            color: 'white', border: 'none', borderRadius: 7,
            cursor: !canManage ? 'not-allowed' : (busy ? 'default' : 'pointer'),
            opacity: !canManage ? 0.55 : 1,
            fontFamily: 'inherit',
          }}>Add</button>
      </form>
      {!canManage && (
        <div style={{ fontSize: 11.5, color: 'var(--ink-500)', fontStyle: 'italic' }}>
          Only admins can add or remove authorized users.
        </div>
      )}
      {users.loading && <div style={{ color: 'var(--ink-500)', fontSize: 12.5 }}>Loading…</div>}
      {users.error && <window.ErrorBanner error={users.error} onRetry={users.reload}/>}
      {!users.loading && !users.error && !rows.length && (
        <div style={{ fontSize: 12.5, color: 'var(--ink-500)' }}>No authorized users configured.</div>
      )}
      {rows.map(u => (
        <div key={u.id} style={{
          display: 'flex', alignItems: 'center', gap: 12,
          padding: '8px 12px', background: 'var(--ink-50)', borderRadius: 8, fontSize: 12.5
        }}>
          <span style={{ color: 'var(--ink-900)', fontWeight: 500 }}>{u.display_name || '—'}</span>
          <span style={{ color: 'var(--ink-600)', fontFamily: 'var(--font-mono)', fontSize: 11.5, flex: 1 }}>{u.email}</span>
          <span style={{
            padding: '2px 7px', fontSize: 10.5, borderRadius: 999,
            background: u.is_active ? 'var(--buy-soft)' : 'var(--ink-100)',
            color: u.is_active ? 'var(--buy)' : 'var(--ink-500)',
            fontFamily: 'var(--font-mono)', fontWeight: 600
          }}>{u.is_active ? 'ACTIVE' : 'INACTIVE'}</span>
          {(u.is_elevated || _isAdminByEmail(u.email)) && (
            <span style={{
              padding: '2px 7px', fontSize: 10.5, borderRadius: 999,
              background: '#FEF3C7',          // amber-100 soft fill
              color: '#D97706',                // amber-600 text
              fontFamily: 'var(--font-mono)', fontWeight: 600,
              border: '1px solid #FDE68A',
            }}>ADMIN</span>
          )}
          <button
            onClick={() => canManage && toggleAdmin(u)}
            disabled={!canManage || busy}
            title={
              !canManage ? 'Restricted — only admins can change roles.'
              : (u.is_elevated ? 'Demote to standard user' : 'Promote to admin')
            }
            style={{
              padding: '4px 10px', fontSize: 11,
              background: 'transparent',
              color: !canManage ? 'var(--ink-400)' : (u.is_elevated ? 'var(--ink-600)' : '#D97706'),
              border: '1px solid ' + (u.is_elevated ? 'var(--ink-200)' : '#FDE68A'),
              borderRadius: 6,
              cursor: !canManage ? 'not-allowed' : 'pointer',
              opacity: !canManage ? 0.55 : 1,
              fontFamily: 'inherit',
            }}
          >{u.is_elevated ? 'Demote' : 'Promote'}</button>
          <button
            onClick={() => canManage && remove(u.id)}
            disabled={!canManage}
            title={!canManage ? 'Restricted — only admins can remove users.' : 'Remove this user'}
            style={{
              padding: '4px 10px', fontSize: 11,
              background: 'transparent',
              color: !canManage ? 'var(--ink-400)' : 'var(--pass)',
              border: '1px solid var(--ink-200)',
              borderRadius: 6,
              cursor: !canManage ? 'not-allowed' : 'pointer',
              opacity: !canManage ? 0.55 : 1,
              fontFamily: 'inherit',
            }}
          >Remove</button>
        </div>
      ))}
    </div>
  );
}

function Card({ title, children }) {
  return (
    <section style={{ background: 'var(--paper)', border: '1px solid var(--ink-150)', borderRadius: 12, overflow: 'hidden' }}>
      <div style={{
        padding: '12px 18px', borderBottom: '1px solid var(--ink-150)',
        fontSize: 12, fontWeight: 600, color: 'var(--ink-900)',
        textTransform: 'uppercase', letterSpacing: '0.06em'
      }}>{title}</div>
      <div style={{ padding: '16px 18px', display: 'flex', flexDirection: 'column', gap: 12 }}>{children}</div>
    </section>
  );
}

function NumField({ label, value, onChange }) {
  return (
    <label style={{ display: 'block' }}>
      <div style={{ fontSize: 11, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 500, marginBottom: 5 }}>{label}</div>
      <input type="number" value={value ?? ''} onChange={e => onChange(e.target.value === '' ? null : Number(e.target.value))} style={{
        width: '100%', padding: '8px 12px', fontSize: 13, background: 'var(--ink-100)',
        border: '1px solid var(--ink-200)', borderRadius: 7, outline: 'none',
        color: 'var(--ink-900)', fontFamily: 'var(--font-mono)'
      }}/>
    </label>
  );
}

function CheckField({ label, checked, onChange }) {
  return (
    <label style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
      <input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)}/>
      <span style={{ fontSize: 13, color: 'var(--ink-800)' }}>{label}</span>
    </label>
  );
}

// Per-channel recipient editor: header + description + toggle + chip list
// editor. The recipient list is stored as a JS array of email strings; the
// editor accepts comma- or newline-separated input and dedupes case-insensitive.
function EmailChannel({ title, description, toggleLabel, toggle, onToggle, recipients, onRecipients }) {
  const { useState } = React;
  const [draft, setDraft] = useState('');

  const list = Array.isArray(recipients) ? recipients : [];

  const addFromDraft = () => {
    const incoming = draft.split(/[,\n]/).map(s => s.trim().toLowerCase()).filter(s => s && s.includes('@'));
    if (!incoming.length) { setDraft(''); return; }
    const seen = new Set(list.map(s => String(s).toLowerCase()));
    const merged = [...list];
    for (const e of incoming) {
      if (!seen.has(e)) { seen.add(e); merged.push(e); }
    }
    onRecipients(merged);
    setDraft('');
  };

  const remove = (email) => {
    onRecipients(list.filter(e => String(e).toLowerCase() !== String(email).toLowerCase()));
  };

  return (
    <div style={{
      padding: 12, background: 'var(--ink-50)', borderRadius: 9,
      border: '1px solid var(--ink-200)', display: 'flex', flexDirection: 'column', gap: 8,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
        <div>
          <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink-900)' }}>{title}</div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-500)', marginTop: 2 }}>{description}</div>
        </div>
        <CheckField label={toggleLabel} checked={toggle} onChange={onToggle}/>
      </div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
        {list.length === 0 && (
          <div style={{ fontSize: 11.5, color: 'var(--ink-500)', fontStyle: 'italic' }}>
            No recipients on this channel.
          </div>
        )}
        {list.map(email => (
          <span key={email} style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '3px 8px', fontSize: 11.5, fontFamily: 'var(--font-mono)',
            background: 'var(--ink-100)', border: '1px solid var(--ink-200)',
            borderRadius: 999, color: 'var(--ink-800)',
          }}>
            {email}
            <button onClick={() => remove(email)} title="Remove" style={{
              background: 'none', border: 'none', cursor: 'pointer',
              color: 'var(--ink-500)', padding: 0, fontSize: 13, lineHeight: 1,
            }}>×</button>
          </span>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 6 }}>
        <input
          value={draft}
          onChange={e => setDraft(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addFromDraft(); } }}
          placeholder="Add email(s), comma- or newline-separated"
          type="text"
          style={{
            flex: 1, padding: '6px 10px', fontSize: 12, background: 'white',
            border: '1px solid var(--ink-200)', borderRadius: 6, outline: 'none',
            color: 'var(--ink-900)', fontFamily: 'var(--font-mono)',
          }}/>
        <button onClick={addFromDraft} disabled={!draft.trim()} style={{
          padding: '6px 12px', fontSize: 12, fontWeight: 500,
          background: draft.trim() ? 'var(--ink-900)' : 'var(--ink-300)',
          color: 'white', border: 'none', borderRadius: 6,
          cursor: draft.trim() ? 'pointer' : 'not-allowed', fontFamily: 'inherit',
        }}>Add</button>
      </div>
    </div>
  );
}

// Fallback admin check when authorized_users.is_elevated isn't populated
// (e.g. migration hasn't run on this Supabase project yet). Mirrors the same
// hardcoded allowlist used by EQ_IS_AUTHORIZED on the client.
function _isAdminByEmail(email) {
  const list = window.EQ_AUTHORIZED_EMAILS || [];
  const e = (email || '').toLowerCase().trim();
  return list.some(x => x.toLowerCase() === e);
}
