import { HelpText } from './HelpText';
import { FieldLabel, FieldInput } from './formUtils';
import type { SectionFormProps } from './types';

/**
 * Reflection (Hermes mode) settings.
 *
 * Toggle + caps for the per-job reflection loop that auto-updates a user's
 * persistent memory. See `src/engine/reflection/` and the design doc at
 * docs/superpowers/specs/2026-05-11-self-improving-memory-design.md.
 *
 * For Reflection to actually run, a worker with `roles: [reflection]` must
 * exist in the LLM Workers tab. Otherwise (with the default `worker_required`)
 * jobs are silently skipped.
 */
export function ReflectionForm({ config, onChange }: SectionFormProps) {
  const reflection = config.reflection ?? {};
  // Step 7 (design 2026-05-21): read v2 `llm.workers`. The v2 API contract
  // already strips the legacy `provider` block from GET /api/config, so
  // falling back to it would always be empty. Kept as a defensive `?? []`
  // for the brief window where draft state may still be undefined.
  const workers = config.llm?.workers ?? [];
  const hasReflectionWorker = workers.some(
    (w: { roles?: string[] }) => Array.isArray(w.roles) && w.roles.includes('reflection'),
  );
  const enabled = reflection.enabled === true;

  return (
    <div className="space-y-5">
      <h2 className="text-base font-semibold text-slate-800">Reflection (Hermes mode)</h2>

      <p className="text-xs text-slate-600 leading-relaxed">
        通常ジョブが完了するたびに LLM がそのジョブから学んだ教訓を抽出し、ユーザーの memory
        (<code className="font-mono text-2xs">data/users/{'{userId}'}/memory/</code>)
        と必要に応じて custom piece を自動更新します。全変更は snapshot として保存され、
        Memory &amp; Learning タブから revert 可能です。
      </p>

      <div>
        <label className="flex items-center gap-2 text-sm text-slate-700">
          <input
            type="checkbox"
            checked={enabled}
            onChange={e => onChange('reflection.enabled', e.target.checked)}
            className="rounded"
          />
          <span className="font-semibold">Reflection を有効化（自動適用）</span>
        </label>
        <HelpText>
          ON にすると、エージェントジョブが終わるたびに reflection ジョブが裏で走り、memory
          を自動で書き換えます。デフォルト: 無効。
        </HelpText>
      </div>

      {enabled && !hasReflectionWorker && (
        <div className="rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900">
          <div className="font-semibold mb-1">⚠ Reflection worker が未設定です</div>
          <div>
            Reflection を有効化しても、<code className="font-mono">roles</code> に
            <code className="font-mono">reflection</code> を含む worker が無いとジョブは
            enqueue されません。<strong>LLM → Workers</strong> タブで以下のような worker
            を追加してください:
          </div>
          <pre className="mt-2 text-2xs font-mono bg-white border border-amber-200 rounded p-2 overflow-auto">{`id: reflection-1
connection_type: direct
endpoint: http://localhost:11434/v1
model: qwen2.5:3b      # cheap モデル推奨
roles: [reflection]
max_concurrency: 1`}</pre>
        </div>
      )}

      <div>
        <label className="flex items-center gap-2 text-sm text-slate-700">
          <input
            type="checkbox"
            checked={reflection.workerRequired !== false}
            onChange={e => onChange('reflection.workerRequired', e.target.checked)}
            className="rounded"
          />
          専用 reflection worker を必須にする
        </label>
        <HelpText>
          ON: <code className="font-mono">roles: [reflection]</code> を持つ worker が無い場合、
          reflection ジョブを enqueue せずスキップします (デフォルト)。OFF にすると enabled
          のみで他 worker に拾われる可能性あり。
        </HelpText>
      </div>

      <h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Caps</h3>

      <div>
        <FieldLabel>Max memory changes per job</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.maxMemoryChangesPerJob ?? 3}
          onChange={v => onChange('reflection.maxMemoryChangesPerJob', Number(v))}
        />
        <HelpText>1 ジョブの reflection で書き込める memory entry の上限。デフォルト: 3</HelpText>
      </div>

      <div>
        <FieldLabel>Max entry body bytes</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.maxEntryBodyBytes ?? 8192}
          onChange={v => onChange('reflection.maxEntryBodyBytes', Number(v))}
        />
        <HelpText>memory entry body の最大バイト数。これを超えると semantic validator が reject。デフォルト: 8192</HelpText>
      </div>

      <div>
        <FieldLabel>Piece edit cooldown (hours)</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.pieceEditCooldownHours ?? 24}
          onChange={v => onChange('reflection.pieceEditCooldownHours', Number(v))}
        />
        <HelpText>同じ piece への連続編集を抑制する cooldown。デフォルト: 24 (24h 以内に 2 回編集されたら 3 回目以降はスキップ)</HelpText>
      </div>

      <div>
        <FieldLabel>Activity log max bytes</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.activityLogMaxBytes ?? 4096}
          onChange={v => onChange('reflection.activityLogMaxBytes', Number(v))}
        />
        <HelpText>reflection LLM に渡す activity log の圧縮上限。デフォルト: 4096</HelpText>
      </div>

      <h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Budget</h3>

      <div>
        <FieldLabel>Per-user daily budget (tokens)</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.perUserDailyBudgetTokens ?? 200000}
          onChange={v => onChange('reflection.perUserDailyBudgetTokens', Number(v))}
        />
        <HelpText>1 ユーザーが 1 日に reflection で消費できる token 合計。超えた以降の reflection は enqueue されません。デフォルト: 200000</HelpText>
      </div>

      <h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Snapshot &amp; Retention</h3>

      <div>
        <FieldLabel>Snapshot retention (days)</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.snapshotRetentionDays ?? 90}
          onChange={v => onChange('reflection.snapshotRetentionDays', Number(v))}
        />
        <HelpText>reflection-history snapshot の保持日数。デフォルト: 90</HelpText>
      </div>

      <div>
        <FieldLabel>Snapshot max bytes per user</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.snapshotMaxBytesPerUser ?? 100 * 1024 * 1024}
          onChange={v => onChange('reflection.snapshotMaxBytesPerUser', Number(v))}
        />
        <HelpText>1 ユーザーあたりの snapshot ディレクトリ合計サイズ上限 (bytes)。超えると古い順に削除。デフォルト: 100 MiB</HelpText>
      </div>

      <div>
        <FieldLabel>Snapshot max bytes per entry</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.snapshotMaxBytesPerEntry ?? 1 * 1024 * 1024}
          onChange={v => onChange('reflection.snapshotMaxBytesPerEntry', Number(v))}
        />
        <HelpText>1 snapshot エントリの最大サイズ (bytes)。デフォルト: 1 MiB</HelpText>
      </div>

      <div>
        <label className="flex items-center gap-2 text-sm text-slate-700">
          <input
            type="checkbox"
            checked={reflection.storeLlmRaw === true}
            onChange={e => onChange('reflection.storeLlmRaw', e.target.checked)}
            className="rounded"
          />
          スナップショットに LLM の生レスポンスを保存する
        </label>
        <HelpText>
          ON にすると <code className="font-mono">llm-raw.json</code> を snapshot に含めます。
          デバッグ用途、デフォルトは OFF (ディスク節約)。
        </HelpText>
      </div>

      <h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Monitoring</h3>

      <div>
        <FieldLabel>Abstain rate floor</FieldLabel>
        <FieldInput
          type="number"
          value={reflection.abstainRateFloor ?? 0.3}
          onChange={v => onChange('reflection.abstainRateFloor', v ? Number(v) : undefined)}
        />
        <HelpText>
          abstain (学ぶことなし) 率がこれを下回ると過剰学習サインとして警告 (運用シグナル)。
          デフォルト: 0.3。この値を下回った場合はシステムログに warn が出ます。
          反映率が高すぎる場合は max_memory_changes_per_job を下げることを検討してください。
        </HelpText>
      </div>
    </div>
  );
}
