/**
 * Static provider mode metadata — lifted from Paseo provider-manifest.ts patterns.
 */
import type { ProviderMode } from './provider-types.js';

export interface ProviderManifestEntry {
  defaultModeId: string | null;
  modes: ProviderMode[];
  /** Claude effort levels exposed as thinking options on models. */
  thinkingOptions?: Array<{ id: string; label: string }>;
}

const CLAUDE_MODES: ProviderMode[] = [
  { id: 'default', label: 'Always Ask', description: 'Prompts for permission the first time a tool is used' },
  { id: 'auto', label: 'Auto mode', description: 'Model classifier reviews permission prompts automatically' },
  { id: 'acceptEdits', label: 'Accept File Edits', description: 'Automatically approves edit-focused tools' },
  { id: 'plan', label: 'Plan Mode', description: 'Analyze without executing tools or edits' },
  { id: 'bypassPermissions', label: 'Bypass', description: 'Skip all permission prompts', isUnattended: true },
];

const OPENCODE_MODES: ProviderMode[] = [
  { id: 'build', label: 'Build', description: 'Allows edits and tool execution' },
  { id: 'plan', label: 'Plan', description: 'Read-only planning mode' },
  { id: 'full-access', label: 'Full Access', description: 'Auto-approves all tool prompts', isUnattended: true },
];

const QWEN_PTY_MODES: ProviderMode[] = [
  { id: 'default', label: 'Default', description: 'Prompt for approval' },
  { id: 'plan', label: 'Plan', description: 'Plan only — no edits' },
  { id: 'auto-edit', label: 'Auto Edit', description: 'Auto-approve edit tools' },
  { id: 'auto', label: 'Auto', description: 'LLM classifier auto-approves safe actions' },
  { id: 'yolo', label: 'YOLO', description: 'Auto-approve all tools', isUnattended: true },
];

const REASONIX_MODES: ProviderMode[] = [
  { id: 'ask', label: 'Ask', description: 'Prompt before permission-gated tool calls' },
  { id: 'yolo', label: 'YOLO', description: 'Auto-approve permission-gated tool calls', isUnattended: true },
];

// Native BooCode (llama-swap) has no agent-native mode vocabulary, so we define
// one that matches the unified permission ladder. `bypass` is the only mode that
// changes behavior (auto-apply staged edits after the turn — dispatcher.ts);
// `plan` falls back to `ask` semantics for native (writes still stage to the
// pending-changes queue). External agents map the same three unified modes onto
// THEIR native ids via the `plan`-id / default / `isUnattended` shape.
const BOOCODE_MODES: ProviderMode[] = [
  { id: 'plan', label: 'Plan', description: 'Read-only analysis (native BooCode falls back to Ask)' },
  { id: 'ask', label: 'Ask Permission', description: 'Stage edits to the pending-changes queue for review' },
  { id: 'bypass', label: 'Bypass', description: 'Auto-apply edits to disk after the turn', isUnattended: true },
];

const CLAUDE_THINKING = [
  { id: 'low', label: 'Low' },
  { id: 'medium', label: 'Medium' },
  { id: 'high', label: 'High' },
  { id: 'xhigh', label: 'Extra High' },
  { id: 'max', label: 'Max' },
];

export const PROVIDER_MANIFEST: Record<string, ProviderManifestEntry> = {
  boocode: {
    defaultModeId: 'ask',
    modes: BOOCODE_MODES,
  },
  claude: {
    defaultModeId: 'default',
    modes: CLAUDE_MODES,
    thinkingOptions: CLAUDE_THINKING,
  },
  opencode: {
    defaultModeId: 'build',
    modes: OPENCODE_MODES,
  },
  goose: {
    defaultModeId: null,
    modes: [],
  },
  reasonix: {
    defaultModeId: 'ask',
    modes: REASONIX_MODES,
  },
  qwen: {
    defaultModeId: 'default',
    modes: QWEN_PTY_MODES,
  },
};

export function getManifestModes(provider: string): ProviderMode[] {
  return PROVIDER_MANIFEST[provider]?.modes ?? [];
}

export function getManifestDefaultModeId(provider: string): string | null {
  return PROVIDER_MANIFEST[provider]?.defaultModeId ?? null;
}

export function isUnattendedMode(provider: string, modeId: string | undefined): boolean {
  if (!modeId) return false;
  const modes = getManifestModes(provider);
  return modes.some((m) => m.id === modeId && m.isUnattended);
}
