// Settings page — workspace, members, orchestration policy, security, integrations, API keys

// ---------- Form atoms ----------
function Switch({ checked, onChange }) {
  return (
    <label className={`switch ${checked ? 'on' : ''}`}>
      <input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)} />
      <span className="switch-track" />
      <span className="switch-thumb" />
    </label>
  );
}

function Seg({ value, onChange, options }) {
  return (
    <div className="seg" role="tablist">
      {options.map(o => (
        <button
          key={o.value}
          type="button"
          className={value === o.value ? 'active' : ''}
          onClick={() => onChange(o.value)}
        >{o.label}</button>
      ))}
    </div>
  );
}

function Field({ label, hint, children, stack, badge }) {
  return (
    <div className={`set-field ${stack ? 'stack' : ''}`}>
      <div className="set-field-main">
        <div className="set-field-label">{label}{badge}</div>
        {hint && <div className="set-field-hint">{hint}</div>}
      </div>
      <div className="set-control">{children}</div>
    </div>
  );
}

function SectionHead({ title, sub, action }) {
  return (
    <div className="set-section-head">
      <div style={{ flex: 1 }}>
        <h2 className="set-section-title">{title}</h2>
        <p className="set-section-sub">{sub}</p>
      </div>
      {action}
    </div>
  );
}

function Panel({ icon, title, right, children, danger }) {
  return (
    <div className={`panel ${danger ? 'danger' : ''}`}>
      <div className="panel-head">
        {icon && <Icon name={icon} size={14} />}
        <span className="panel-title">{title}</span>
        {right && <span style={{ marginLeft: 'auto', display: 'flex', gap: 6, alignItems: 'center' }}>{right}</span>}
      </div>
      <div className="panel-body" style={{ padding: 0 }}>{children}</div>
    </div>
  );
}

// ---------- Sections ----------
function GeneralSection({ s, set }) {
  return (
    <div className="settings-content">
      <SectionHead
        title="General"
        sub="Workspace identity, environment, and default region for dispatched tasks."
        action={<span className="save-hint"><Icon name="check" size={12} />Saved 2m ago</span>}
      />

      <Panel icon="settings" title="Workspace">
        <Field label="Workspace name" hint="Shown in the sidebar and on every audit-log entry.">
          <input className="input w-220" value={s.wsName} onChange={e => set('wsName', e.target.value)} />
        </Field>
        <Field label="Workspace handle" hint="Used in API hostnames and the registry namespace.">
          <span className="input-prefix">
            <span className="pfx">orchestra.dev/</span>
            <input className="input mono" style={{ width: 130 }} value={s.wsSlug} onChange={e => set('wsSlug', e.target.value)} />
          </span>
        </Field>
        <Field label="Environment" hint="Controls the badge shown across the console and which key-set agents use.">
          <Seg value={s.env} onChange={v => set('env', v)} options={[
            { value: 'prod', label: 'Production' },
            { value: 'staging', label: 'Staging' },
          ]} />
        </Field>
        <Field label="Default region" hint="Where new agents and provisioned resources land unless overridden per task.">
          <select className="select" value={s.region} onChange={e => set('region', e.target.value)}>
            <option value="us-east-2">us-east-2 · Ohio</option>
            <option value="us-west-1">us-west-1 · N. California</option>
            <option value="eu-central-1">eu-central-1 · Frankfurt</option>
            <option value="ap-southeast-1">ap-southeast-1 · Singapore</option>
          </select>
        </Field>
      </Panel>

      <Panel icon="alert" title="Danger zone" danger>
        <Field label="Transfer ownership" hint="Move billing and root admin to another member. Requires their confirmation.">
          <button className="btn" type="button">Transfer…</button>
        </Field>
        <Field label="Delete workspace" hint="Permanently remove all projects, agents, and audit history. Cannot be undone.">
          <button className="btn danger" type="button"><Icon name="trash" size={12} />Delete workspace</button>
        </Field>
      </Panel>
    </div>
  );
}

const MEMBERS = [
  { name: 'Kavi Rao', email: 'kavi.r@zenix.team', role: 'owner', seen: 'online', color: 'linear-gradient(135deg, oklch(0.65 0.15 30), oklch(0.6 0.18 350))' },
  { name: 'Dana Whitfield', email: 'dana.w@zenix.team', role: 'admin', seen: '12m ago', color: 'oklch(0.6 0.16 280)' },
  { name: 'Marco Liu', email: 'marco.l@zenix.team', role: 'operator', seen: '1h ago', color: 'oklch(0.62 0.15 200)' },
  { name: 'Priya Nair', email: 'priya.n@zenix.team', role: 'operator', seen: '3h ago', color: 'oklch(0.62 0.15 150)' },
  { name: 'Sam Okonkwo', email: 'sam.o@zenix.team', role: 'viewer', seen: 'yesterday', color: 'oklch(0.65 0.16 60)' },
];

function MembersSection() {
  return (
    <div className="settings-content">
      <SectionHead
        title="Members & roles"
        sub="People with access to this workspace. Roles gate which actions an account can approve."
        action={<button className="btn primary" type="button"><Icon name="plus" size={12} />Invite member</button>}
      />

      <Panel icon="users" title="Members" right={<span className="chip-mono" style={{ color: 'var(--c-text-3)' }}>{MEMBERS.length} active · 1 pending</span>}>
        {MEMBERS.map(m => (
          <div className="member-row" key={m.email}>
            <div className="member-avatar" style={{ background: m.color }}>
              {m.name.split(' ').map(w => w[0]).join('')}
            </div>
            <div style={{ minWidth: 0 }}>
              <div className="member-name">{m.name}</div>
              <div className="member-email">{m.email}</div>
            </div>
            <div className="member-seen">
              {m.seen === 'online'
                ? <span className="s-done" style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><span className="dot pulse" />online</span>
                : m.seen}
            </div>
            {m.role === 'owner'
              ? <span className="badge live" style={{ minWidth: 70, justifyContent: 'center' }}>owner</span>
              : (
                <select className="select" defaultValue={m.role} style={{ width: 110 }}>
                  <option value="admin">Admin</option>
                  <option value="operator">Operator</option>
                  <option value="viewer">Viewer</option>
                </select>
              )}
          </div>
        ))}
      </Panel>

      <Panel icon="clock" title="Pending invites">
        <div className="member-row" style={{ gridTemplateColumns: '30px 1fr auto auto' }}>
          <div className="member-avatar" style={{ background: 'var(--c-surface-3)', color: 'var(--c-text-3)' }}>?</div>
          <div>
            <div className="member-name" style={{ color: 'var(--c-text-2)' }}>jordan.k@zenix.team</div>
            <div className="member-email">invited by Kavi · expires in 6 days</div>
          </div>
          <span className="badge review">operator</span>
          <div className="row-actions">
            <button className="btn sm ghost" type="button">Resend</button>
            <button className="btn sm ghost icon" type="button" title="Revoke"><Icon name="x" size={13} /></button>
          </div>
        </div>
      </Panel>
    </div>
  );
}

function OrchestrationSection({ s, set }) {
  return (
    <div className="settings-content">
      <SectionHead
        title="Orchestration policy"
        sub="The guardrails the orchestrator obeys when dispatching, approving, and recovering agent tasks."
      />

      <Panel icon="cpu" title="Autonomy">
        <Field
          label="Autonomy mode"
          hint="Supervised pauses before every action; Autonomous runs the full graph and only stops on policy gates below."
        >
          <Seg value={s.autonomy} onChange={v => set('autonomy', v)} options={[
            { value: 'supervised', label: 'Supervised' },
            { value: 'semi', label: 'Semi-auto' },
            { value: 'auto', label: 'Autonomous' },
          ]} />
        </Field>
        <Field label="Max concurrent agents" hint="Hard ceiling on agents executing at once across all projects.">
          <input className="input mono w-120" type="number" min="1" max="32" value={s.maxAgents} onChange={e => set('maxAgents', +e.target.value)} />
        </Field>
        <Field label="Dispatch queue depth" hint="How many validated tasks may sit in Ready before backpressure throttles intake.">
          <input className="input mono w-120" type="number" min="1" max="100" value={s.queueDepth} onChange={e => set('queueDepth', +e.target.value)} />
        </Field>
      </Panel>

      <Panel icon="shield" title="Approval gates">
        <Field label="Require approval — database changes" hint="Migrations, backfills, and schema edits land in Review before they run.">
          <Switch checked={s.gateDb} onChange={v => set('gateDb', v)} />
        </Field>
        <Field label="Require approval — production deploys" hint="Anything targeting a prod environment waits for a human.">
          <Switch checked={s.gateProd} onChange={v => set('gateProd', v)} />
        </Field>
        <Field label="Require approval — high-priority tasks" hint="Tasks flagged high always route through Review regardless of type.">
          <Switch checked={s.gateHigh} onChange={v => set('gateHigh', v)} />
        </Field>
      </Panel>

      <Panel icon="rotate" title="Recovery">
        <Field label="Auto-retry failed tasks" hint="Re-dispatch on transient failures before halting the column.">
          <Switch checked={s.autoRetry} onChange={v => set('autoRetry', v)} />
        </Field>
        <Field label="Max retry attempts" hint="Exponential backoff between attempts; after this the task moves to Failed.">
          <input className="input mono w-120" type="number" min="0" max="10" value={s.maxRetries} onChange={e => set('maxRetries', +e.target.value)} disabled={!s.autoRetry} style={{ opacity: s.autoRetry ? 1 : 0.5 }} />
        </Field>
        <Field label="Auto-rollback on failure" hint="Revert partial changes via the rollback-agent when a task halts mid-flight.">
          <Switch checked={s.autoRollback} onChange={v => set('autoRollback', v)} />
        </Field>
        <Field label="Quiet hours" hint="Suspend autonomous production deploys during this window (workspace timezone).">
          <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <input className="input mono" style={{ width: 78 }} value={s.quietFrom} onChange={e => set('quietFrom', e.target.value)} />
            <span style={{ color: 'var(--c-text-4)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>→</span>
            <input className="input mono" style={{ width: 78 }} value={s.quietTo} onChange={e => set('quietTo', e.target.value)} />
          </span>
        </Field>
      </Panel>
    </div>
  );
}

function SecuritySection({ s, set }) {
  return (
    <div className="settings-content">
      <SectionHead
        title="Security"
        sub="Authentication, session, and network controls for everyone in the workspace."
      />

      <Panel icon="shield" title="Authentication">
        <Field label="Enforce two-factor auth" hint="Every member must register a TOTP app or passkey before next sign-in.">
          <Switch checked={s.mfa} onChange={v => set('mfa', v)} />
        </Field>
        <Field
          label="SSO / SAML"
          badge={<span className="badge live" style={{ marginLeft: 8 }}>connected</span>}
          hint="Okta · login.zenix.team — last metadata sync 2 days ago."
        >
          <button className="btn" type="button"><Icon name="settings" size={12} />Configure</button>
        </Field>
        <Field label="SCIM provisioning" hint="Auto-create and deprovision members from your identity provider.">
          <Switch checked={s.scim} onChange={v => set('scim', v)} />
        </Field>
      </Panel>

      <Panel icon="clock" title="Sessions & network">
        <Field label="Session timeout" hint="Idle members are signed out automatically after this period.">
          <select className="select" value={s.sessionTimeout} onChange={e => set('sessionTimeout', e.target.value)}>
            <option value="4h">4 hours</option>
            <option value="12h">12 hours</option>
            <option value="24h">24 hours</option>
            <option value="7d">7 days</option>
          </select>
        </Field>
        <Field
          label="IP allowlist"
          stack
          hint="Restrict console and API access to these CIDR ranges. One per line — leave empty to allow all."
        >
          <textarea className="input w-full" rows="3" value={s.ipAllow} onChange={e => set('ipAllow', e.target.value)} />
        </Field>
      </Panel>
    </div>
  );
}

const INTEGRATIONS = [
  { id: 'slack', name: 'Slack', icon: '#', bg: 'oklch(0.6 0.14 320)', desc: 'Posts approvals, halts, and completions to #orchestra-ops.', status: 'connected' },
  { id: 'github', name: 'GitHub', icon: 'GH', bg: 'oklch(0.4 0.02 260)', desc: 'Opens PRs for code-changing tasks · zenix-team org.', status: 'connected' },
  { id: 'registry', name: 'Module registry', icon: '◷', bg: 'oklch(0.58 0.19 280)', desc: 'registry.orchestra.prod — signed package source.', status: 'connected' },
  { id: 'datadog', name: 'Datadog', icon: 'DD', bg: 'oklch(0.55 0.18 300)', desc: 'Stream agent metrics and traces to your dashboards.', status: 'available' },
  { id: 'pagerduty', name: 'PagerDuty', icon: 'PD', bg: 'oklch(0.6 0.16 150)', desc: 'Page the on-call when a task halts in production.', status: 'available' },
];

function IntegrationsSection() {
  return (
    <div className="settings-content">
      <SectionHead
        title="Integrations"
        sub="Connect Orchestra to the tools your team already runs."
        action={<button className="btn" type="button"><Icon name="refresh" size={12} />Sync now</button>}
      />
      <Panel icon="link" title="Connections" right={<span className="chip-mono" style={{ color: 'var(--c-text-3)' }}>3 connected</span>}>
        {INTEGRATIONS.map(it => (
          <div className="intg-row" key={it.id}>
            <div className="intg-icon" style={{ background: it.bg }}>{it.icon}</div>
            <div style={{ minWidth: 0 }}>
              <div className="intg-name">{it.name}</div>
              <div className="intg-desc">{it.desc}</div>
            </div>
            {it.status === 'connected'
              ? <div className="row-actions">
                  <span className="badge live" style={{ marginRight: 4 }}>connected</span>
                  <button className="btn sm ghost icon" type="button" title="Manage"><Icon name="more" size={13} /></button>
                </div>
              : <button className="btn sm" type="button"><Icon name="plus" size={11} />Connect</button>}
          </div>
        ))}
      </Panel>
    </div>
  );
}

const KEYS = [
  { id: 'k1', label: 'CI pipeline', prefix: 'orc_live_7f3a', scope: 'write', last: '4m ago', created: 'Mar 2, 2026' },
  { id: 'k2', label: 'Grafana exporter', prefix: 'orc_live_b21c', scope: 'read', last: '1h ago', created: 'Jan 18, 2026' },
  { id: 'k3', label: 'Local dev — kavi', prefix: 'orc_test_9d04', scope: 'write', last: '3d ago', created: 'Feb 27, 2026' },
];

function ApiSection() {
  return (
    <div className="settings-content">
      <SectionHead
        title="API keys"
        sub="Programmatic access to dispatch tasks and read orchestrator state. Treat keys like passwords."
        action={<button className="btn primary" type="button"><Icon name="plus" size={12} />Create key</button>}
      />
      <Panel icon="key" title="Active keys" right={<span className="chip-mono" style={{ color: 'var(--c-text-3)' }}>{KEYS.length} keys</span>}>
        {KEYS.map(k => (
          <div className="key-row" key={k.id}>
            <div style={{ minWidth: 0 }}>
              <div className="key-token">
                {k.prefix}<span className="reveal">····································</span>
                <button className="btn sm ghost icon" type="button" title="Copy"><Icon name="copy" size={12} /></button>
              </div>
              <div className="key-sub">
                <span style={{ color: 'var(--c-text-2)', fontWeight: 600 }}>{k.label}</span>
                <span>created {k.created}</span>
                <span>last used {k.last}</span>
              </div>
            </div>
            <span className={`scope-pill ${k.scope}`}>{k.scope === 'write' ? 'read · write' : 'read only'}</span>
            <button className="btn sm danger" type="button">Revoke</button>
          </div>
        ))}
      </Panel>
      <div className="empty" style={{ textAlign: 'left', padding: '12px 14px', display: 'flex', gap: 10, alignItems: 'center' }}>
        <Icon name="alert" size={14} />
        A key's full secret is shown only once at creation. Rotate keys every 90 days.
      </div>
    </div>
  );
}

// ---------- Page shell ----------
function ConnectionsSection() {
  const [conns, setConns] = React.useState([]);
  const [prompts, setPrompts] = React.useState({});
  const [busy, setBusy] = React.useState(null);

  const load = React.useCallback(() => {
    window.ORC_API.getConnections().then(setConns).catch(() => {});
  }, []);

  React.useEffect(() => {
    load();
    const es = window.ORC_API.stream(ev => {
      if (ev.type !== 'auth') return;
      setPrompts(p => ({
        ...p,
        [ev.backend]: {
          url: ev.url ?? p[ev.backend]?.url,
          code: ev.code ?? p[ev.backend]?.code,
          message: ev.message ?? p[ev.backend]?.message,
          status: ev.status ?? p[ev.backend]?.status,
        },
      }));
      if (ev.status === 'connected') load();
    });
    const t = setInterval(load, 5000);
    return () => { es.close(); clearInterval(t); };
  }, [load]);

  async function connect(id) {
    setBusy(id);
    try {
      const r = await window.ORC_API.loginConnection(id);
      setPrompts(p => ({ ...p, [id]: { url: r.url, code: r.code, message: r.message, status: r.mode === 'manual' ? 'manual' : 'pending' } }));
    } catch (e) {
      setPrompts(p => ({ ...p, [id]: { status: 'error', message: e.message } }));
    } finally {
      setBusy(null);
    }
  }

  const meta = {
    codex: { name: 'Codex CLI', sub: 'OpenAI · ChatGPT subscription · device login' },
    gemini: { name: 'Gemini CLI', sub: 'Google AI Pro/Ultra · copy ~/.gemini cache' },
  };
  const stateColor = (st) => st === 'connected' ? 'var(--c-status-done)' : st === 'expired' ? 'var(--c-status-review)' : 'var(--c-text-3)';

  return (
    <div className="settings-content">
      <SectionHead title="Connections" sub="Subscription-auth AI agent CLIs. Tokens stay in each CLI's cache — no API keys." />
      {conns.map(c => {
        const m = meta[c.id] || { name: c.id, sub: c.kind };
        const pr = prompts[c.id];
        return (
          <Panel key={c.id} icon="cpu" title={m.name}
            right={<span className="chip chip-mono"><span className="dot" style={{ background: stateColor(c.auth.state) }} />{c.auth.state}</span>}>
            <Field label={m.sub} hint={c.auth.detail} stack>
              <button className="btn primary" type="button" disabled={busy === c.id} onClick={() => connect(c.id)}>
                <Icon name={c.authMode === 'device' ? 'cpu' : 'open'} size={12} />
                {c.auth.state === 'connected' ? 'Reconnect' : c.authMode === 'device' ? 'Connect (device)' : 'How to connect'}
              </button>
            </Field>
            {pr && (
              <div style={{ padding: '12px 16px', borderTop: '1px solid var(--c-line)', fontFamily: 'var(--font-mono)', fontSize: 12, lineHeight: 1.6 }}>
                {pr.url && <div style={{ marginBottom: 8 }}>1. Open <a href={pr.url} target="_blank" rel="noopener noreferrer" style={{ color: 'var(--c-accent)' }}>{pr.url}</a></div>}
                {pr.code && <div style={{ marginBottom: 8 }}>2. Enter code: <b style={{ fontSize: 16, letterSpacing: '0.08em' }}>{pr.code}</b></div>}
                {pr.message && <div style={{ color: 'var(--c-text-2)', textWrap: 'pretty' }}>{pr.message}</div>}
                {pr.status && <div style={{ marginTop: 8, color: pr.status === 'connected' ? 'var(--c-status-done)' : pr.status === 'error' ? 'var(--c-status-failed)' : 'var(--c-text-3)' }}>status: {pr.status}</div>}
              </div>
            )}
          </Panel>
        );
      })}
      {conns.length === 0 && <div className="empty">no backends</div>}
    </div>
  );
}

const SETTINGS_NAV = [
  { id: 'general', name: 'General', icon: 'settings' },
  { id: 'members', name: 'Members', icon: 'users', count: '6' },
  { id: 'connections', name: 'Connections', icon: 'cpu' },
  { id: 'orchestration', name: 'Orchestration', icon: 'cpu' },
  { id: 'security', name: 'Security', icon: 'shield' },
  { id: 'integrations', name: 'Integrations', icon: 'link', count: '3' },
  { id: 'api', name: 'API keys', icon: 'key' },
];

function SettingsPage() {
  const [section, setSection] = React.useState('general');
  const [s, setS] = React.useState({
    wsName: 'Zenix Team',
    wsSlug: 'zenix-team',
    env: 'prod',
    region: 'us-east-2',
    autonomy: 'semi',
    maxAgents: 6,
    queueDepth: 12,
    gateDb: true,
    gateProd: true,
    gateHigh: false,
    autoRetry: true,
    maxRetries: 3,
    autoRollback: true,
    quietFrom: '23:00',
    quietTo: '06:00',
    mfa: true,
    scim: false,
    sessionTimeout: '12h',
    ipAllow: '10.0.0.0/8\n52.18.44.12/32',
  });
  const set = (k, v) => setS(prev => ({ ...prev, [k]: v }));

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Settings</h1>
          <p className="page-sub">Workspace · zenix-team · 6 members · plan Scale</p>
        </div>
      </div>

      <div className="settings-layout">
        <nav className="settings-nav">
          <div className="nav-section">Workspace</div>
          {SETTINGS_NAV.map(n => (
            <button
              key={n.id}
              type="button"
              className={`set-nav-item ${section === n.id ? 'active' : ''}`}
              onClick={() => setSection(n.id)}
            >
              <Icon name={n.icon} size={15} />
              <span>{n.name}</span>
              {n.count && <span className="set-nav-count">{n.count}</span>}
            </button>
          ))}
        </nav>

        {section === 'general' && <GeneralSection s={s} set={set} />}
        {section === 'members' && <MembersSection />}
        {section === 'connections' && <ConnectionsSection />}
        {section === 'orchestration' && <OrchestrationSection s={s} set={set} />}
        {section === 'security' && <SecuritySection s={s} set={set} />}
        {section === 'integrations' && <IntegrationsSection />}
        {section === 'api' && <ApiSection />}
      </div>
    </div>
  );
}

window.SettingsPage = SettingsPage;
// Shared form atoms reused by the agent editor
Object.assign(window, { Switch, Seg, Field, SectionHead, Panel });
