// SettingsPage — sidebar groups + scrollable form (matches existing SettingsSidebar structure)

const SETTINGS_GROUPS = [
  {
    label: '基本設定',
    sections: [
      { id: 'general',   label: 'General',   desc: 'タイムゾーン・言語' },
      { id: 'provider',  label: 'Provider',  desc: 'LLM API キー・デフォルトモデル' },
      { id: 'workers',   label: 'Workers',   desc: '並列数・タイムアウト・リトライ' },
      { id: 'workspace', label: 'Workspace', desc: '作業ディレクトリ・クリーンアップ' },
      { id: 'progress',  label: 'Progress',  desc: '進捗報告の頻度' },
    ],
  },
  {
    label: 'セキュリティ・アクセス制御',
    sections: [
      { id: 'repos',           label: 'Repos',           desc: 'Gitea 接続・許可リポジトリ' },
      { id: 'access-control',  label: 'Access Control',  desc: 'ロール・権限マトリクス' },
      { id: 'search-filter',   label: 'Search Filter',   desc: 'NGワード・ドメイン制限' },
    ],
  },
  {
    label: 'ツール設定',
    sections: [
      { id: 'tools',            label: 'Tools',     desc: '利用可能なツールの有効化' },
      { id: 'browser-settings', label: 'Browser',   desc: 'noVNC・セッション' },
    ],
  },
  {
    label: 'エージェント制御',
    sections: [
      { id: 'ask-subtasks',  label: 'Ask / Subtasks', desc: 'ASK・サブタスクの挙動' },
      { id: 'context',       label: 'Context',        desc: 'コンテキスト長・注入ルール' },
      { id: 'memory-safety', label: 'Memory / Safety', desc: 'メモリ制限・安全装置' },
    ],
  },
];

const PIECES = ['auto', 'chat', 'research', 'general', 'x-ai-digest', 'brainstorming', 'data-process'];

function SettingsSidebar({ section, onSelect, piece, onSelectPiece }) {
  const itemStyle = (active) => ({
    display: 'block', width: '100%', textAlign: 'left',
    padding: '6px 10px', borderRadius: 8, border: 'none', cursor: 'pointer',
    fontSize: 12, fontFamily: 'inherit', marginBottom: 1,
    background: active ? '#eff6ff' : 'transparent',
    color: active ? '#1d4ed8' : '#475569',
    fontWeight: active ? 700 : 500,
  });
  return (
    <div style={{ height: '100%', overflowY: 'auto', padding: '12px 10px', background: '#fff', borderRight: '1px solid #e2e8f0' }}>
      {SETTINGS_GROUPS.map(g => (
        <div key={g.label} style={{ marginBottom: 12 }}>
          <div style={{
            fontSize: 10, fontWeight: 700, color: '#94a3b8', letterSpacing: '.08em',
            textTransform: 'uppercase', padding: '4px 10px 4px', marginBottom: 2,
          }}>{g.label}</div>
          {g.sections.map(s => (
            <button key={s.id} style={itemStyle(section === s.id && !piece)} onClick={() => onSelect(s.id)}>
              {s.label}
            </button>
          ))}
        </div>
      ))}
      <div style={{
        fontSize: 10, fontWeight: 700, color: '#94a3b8', letterSpacing: '.08em',
        textTransform: 'uppercase', padding: '4px 10px 4px', marginBottom: 2,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <span>Pieces</span>
        <button title="Piece を追加" style={{
          border: 'none', background: 'transparent', color: '#2563eb',
          cursor: 'pointer', fontSize: 14, fontWeight: 700, padding: 0, lineHeight: 1,
        }}>+</button>
      </div>
      {PIECES.map(p => (
        <button key={p} style={itemStyle(piece === p)} onClick={() => onSelectPiece(p)}>
          {p}
        </button>
      ))}
    </div>
  );
}

function SaveBar({ onDiscard }) {
  // 3 states: idle / saving / saved / error — demonstrated via toggle
  const [state, setState] = React.useState('idle');
  const [dirty, setDirty] = React.useState(false);
  // mark dirty when any descendant input changes
  const onInput = React.useCallback(() => setDirty(true), []);
  React.useEffect(() => {
    const h = () => setDirty(true);
    document.addEventListener('input', h);
    return () => document.removeEventListener('input', h);
  }, []);
  const save = async () => {
    setState('saving');
    // mock latency; in 1/5 odds surface an error to showcase failure UI
    await new Promise(r => setTimeout(r, 700));
    if (Math.random() < 0.2) {
      setState('error');
      return;
    }
    setState('saved'); setDirty(false);
    setTimeout(() => setState('idle'), 1500);
  };
  const discard = () => { setDirty(false); setState('idle'); onDiscard?.(); };

  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
      {state === 'saved' && (
        <span style={{
          fontSize: 11, color: '#166534', background: '#dcfce7', padding: '3px 8px',
          borderRadius: 9999, fontWeight: 700, display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M5 13l4 4L19 7"/></svg>
          保存しました
        </span>
      )}
      {state === 'error' && (
        <span style={{
          fontSize: 11, color: '#b91c1c', background: '#fee2e2', padding: '3px 8px',
          borderRadius: 9999, fontWeight: 700, display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>⚠ 保存に失敗</span>
      )}
      <button onClick={discard} disabled={!dirty || state === 'saving'} style={{
        padding: '6px 12px', background: '#fff', border: '1px solid #e2e8f0', color: '#475569',
        borderRadius: 8, fontSize: 12, fontWeight: 700,
        cursor: (!dirty || state === 'saving') ? 'not-allowed' : 'pointer',
        opacity: (!dirty || state === 'saving') ? 0.5 : 1,
        fontFamily: 'inherit',
      }}>Discard</button>
      <button onClick={save} disabled={state === 'saving'} style={{
        padding: '6px 14px', background: '#2563eb', border: 'none', color: '#fff',
        borderRadius: 8, fontSize: 12, fontWeight: 700,
        cursor: state === 'saving' ? 'wait' : 'pointer',
        opacity: state === 'saving' ? 0.7 : 1,
        fontFamily: 'inherit', display: 'inline-flex', alignItems: 'center', gap: 6,
      }}>
        {state === 'saving' && <Spinner />}
        {state === 'saving' ? '保存中…' : 'Save & Apply'}
      </button>
    </div>
  );
}

// Simple mock form surface — shows that the detail pane follows the exact same "card with form" rhythm as Schedules/Users.
function SettingsForm({ section, piece }) {
  const meta = (() => {
    for (const g of SETTINGS_GROUPS) for (const s of g.sections) if (s.id === section) return s;
    return null;
  })();
  const title = piece ? `Piece: ${piece}` : (meta?.label || section);
  const desc = piece ? `${piece} ピースの定義・ムーブメント・ツール設定` : (meta?.desc || '');

  // Sample fields per-section (placeholder — the real forms are in gitea-agent-orchestrator/ui)
  const fields = piece ? [
    { label: 'Description', kind: 'text', value: piece === 'auto' ? '入力内容から最適なピースを自動選択' : `${piece} 用の定義` },
    { label: 'Max movements', kind: 'number', value: 25 },
    { label: 'Initial movement', kind: 'select', value: 'execute', options: ['execute', 'plan', 'research'] },
  ] : ({
    provider: [
      { label: 'Default provider', kind: 'select', value: 'anthropic', options: ['anthropic', 'openai', 'google', 'bedrock'] },
      { label: 'Model', kind: 'select', value: 'claude-sonnet-4.5', options: ['claude-sonnet-4.5', 'claude-opus-4', 'gpt-4.1'] },
      { label: 'API key', kind: 'password', value: 'sk-ant-•••••••••••••••••••••••', env: true },
      { label: 'Max tokens', kind: 'number', value: 8192 },
      { label: 'Temperature', kind: 'number', value: 0.7, step: 0.1 },
    ],
    workers: [
      { label: 'Parallel workers', kind: 'number', value: 6 },
      { label: 'Per-task timeout (sec)', kind: 'number', value: 900 },
      { label: 'Max retries', kind: 'number', value: 3 },
      { label: 'Retry backoff (sec)', kind: 'number', value: 60 },
    ],
    general: [
      { label: 'System timezone', kind: 'select', value: 'Asia/Tokyo', options: ['Asia/Tokyo', 'UTC', 'America/Los_Angeles'] },
      { label: 'Language', kind: 'select', value: 'ja', options: ['ja', 'en'] },
      { label: 'Allow anonymous task creation', kind: 'toggle', value: false },
    ],
    repos: [
      { label: 'Gitea URL', kind: 'text', value: 'https://gitea.internal' },
      { label: 'Access token', kind: 'password', value: 'gitea_•••••••••••', env: true },
      { label: 'Allowed repos', kind: 'text', value: 'daichi/*, corp/*', help: 'カンマ区切り・グロブ可' },
    ],
    'access-control': [
      { label: 'Admin ロール allow', kind: 'text', value: '*' },
      { label: 'Operator ロール allow', kind: 'text', value: 'tasks.*, schedules.*' },
      { label: 'Viewer ロール allow', kind: 'text', value: 'tasks.read, schedules.read' },
    ],
    tools: [
      { label: 'Read / Write / Edit', kind: 'toggle', value: true },
      { label: 'Bash', kind: 'toggle', value: true },
      { label: 'Browser (noVNC)', kind: 'toggle', value: true },
      { label: 'WebSearch', kind: 'toggle', value: false },
    ],
    'browser-settings': [
      { label: 'noVNC endpoint', kind: 'text', value: 'https://novnc.internal' },
      { label: 'Session timeout (min)', kind: 'number', value: 30 },
      { label: 'Allow CAPTCHA fallback to human', kind: 'toggle', value: true },
    ],
    'ask-subtasks': [
      { label: 'Max ASK depth', kind: 'number', value: 3 },
      { label: 'Auto-resume after ASK timeout (min)', kind: 'number', value: 60 },
      { label: 'Allow parallel subtasks', kind: 'toggle', value: true },
    ],
    context: [
      { label: 'Context window (tokens)', kind: 'number', value: 200000 },
      { label: 'Auto-compact threshold', kind: 'number', value: 80, help: '% で指定' },
    ],
    'memory-safety': [
      { label: 'Memory limit per worker (MB)', kind: 'number', value: 2048 },
      { label: 'Kill on OOM', kind: 'toggle', value: true },
      { label: 'Safe-mode Bash commands only', kind: 'toggle', value: false },
    ],
    progress: [
      { label: 'Progress update interval (sec)', kind: 'number', value: 15 },
      { label: 'Show subtask progress', kind: 'toggle', value: true },
    ],
    workspace: [
      { label: 'Workspace root', kind: 'text', value: '/var/lib/agent/workspace' },
      { label: 'Clean after task completion', kind: 'toggle', value: false },
    ],
    'search-filter': [
      { label: 'Blocked domains', kind: 'text', value: 'example-bad.com, *.malicious.example' },
      { label: 'NG words', kind: 'text', value: '', help: 'カンマ区切り' },
    ],
  }[section] || []);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>
      {/* Header */}
      <div style={{
        flexShrink: 0, padding: '14px 20px', borderBottom: '1px solid #e2e8f0', background: '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
      }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 10, fontWeight: 700, color: '#64748b', letterSpacing: '.08em', textTransform: 'uppercase' }}>
            {piece ? 'PIECE' : 'SETTINGS'}
          </div>
          <div style={{ fontSize: 15, fontWeight: 700, color: '#0f172a' }}>{title}</div>
          {desc && <div style={{ fontSize: 12, color: '#64748b', marginTop: 2 }}>{desc}</div>}
        </div>
        <div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
          <SaveBar />
        </div>
      </div>

      {/* Body */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 24px', background: '#f8fafc' }}>
        <div style={{ maxWidth: 640, margin: '0 auto' }}>
          <div style={{
            background: '#fff', border: '1px solid #e2e8f0', borderRadius: 16, padding: 20,
            boxShadow: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
          }}>
            {fields.map((f, i) => (
              <FormRow key={i} label={
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                  {f.label}
                  {f.env && <span style={{ fontSize: 9, fontWeight: 700, color: '#92400e', background: '#fef3c7', padding: '1px 5px', borderRadius: 3 }}>ENV</span>}
                </span>
              } help={f.help}>
                {f.kind === 'toggle' ? (
                  <div style={{
                    display: 'inline-flex', alignItems: 'center', width: 44, height: 24, borderRadius: 9999,
                    background: f.value ? '#2563eb' : '#cbd5e1', padding: 2,
                    justifyContent: f.value ? 'flex-end' : 'flex-start', cursor: 'pointer',
                  }}>
                    <div style={{ width: 20, height: 20, borderRadius: 9999, background: '#fff', boxShadow: '0 1px 2px rgb(0 0 0 / .2)' }} />
                  </div>
                ) : f.kind === 'select' ? (
                  <SelectInput value={f.value} onChange={() => {}}>
                    {f.options.map(o => <option key={o} value={o}>{o}</option>)}
                  </SelectInput>
                ) : f.kind === 'password' ? (
                  <TextInput type="password" value={f.value} readOnly={!!f.env}
                    style={{ fontFamily: 'IBM Plex Mono, monospace', background: f.env ? '#f8fafc' : '#fff' }} />
                ) : f.kind === 'number' ? (
                  <TextInput type="number" value={f.value} step={f.step || 1} onChange={() => {}} />
                ) : (
                  <TextInput value={f.value} onChange={() => {}} />
                )}
              </FormRow>
            ))}
            {fields.length === 0 && (
              <EmptyState
                compact
                icon={<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/></svg>}
                title="このセクションは未実装です"
                hint="`gitea-agent-orchestrator/ui` 側で設定項目を追加するとここに表示されます。"
              />
            )}
          </div>
          <div style={{ height: 40 }} />
        </div>
      </div>
    </div>
  );
}

function SettingsPage({ section, setSection, piece, setPiece }) {
  return (
    <div style={{
      flex: 1, minHeight: 0, display: 'grid',
      gridTemplateColumns: '240px 1fr',
      background: '#f1f5f9', gap: 1,
    }}>
      <SettingsSidebar
        section={section} onSelect={(s) => { setSection(s); setPiece(null); }}
        piece={piece} onSelectPiece={(p) => setPiece(p)}
      />
      <div style={{ background: '#fff', minWidth: 0 }}>
        <SettingsForm section={section} piece={piece} />
      </div>
    </div>
  );
}

window.SettingsPage = SettingsPage;
