export type Command =
  | 'dev'
  | 'build'
  | 'init'
  | 'doctor'
  | 'inspector'
  | 'create'
  | 'help'
  | 'version'
  | 'test'
  | 'socket'
  // Process Manager commands
  | 'start'
  | 'stop'
  | 'restart'
  | 'status'
  | 'list'
  | 'logs'
  | 'service'
  // Package Manager commands
  | 'install'
  | 'uninstall'
  | 'configure';

export type DeploymentAdapter = 'node' | 'vercel' | 'lambda' | 'cloudflare' | 'distributed';
export type BuildTarget =
  | 'cli'
  | 'node'
  | 'sdk'
  | 'browser'
  | 'cloudflare'
  | 'vercel'
  | 'lambda'
  | 'distributed'
  | 'mcpb';

const DEPLOYMENT_ADAPTERS: readonly DeploymentAdapter[] = ['node', 'vercel', 'lambda', 'cloudflare', 'distributed'];
const BUILD_TARGETS: readonly BuildTarget[] = [
  'cli',
  'node',
  'sdk',
  'browser',
  'cloudflare',
  'vercel',
  'lambda',
  'distributed',
  'mcpb',
];

export function isDeploymentAdapter(val: string): val is DeploymentAdapter {
  return (DEPLOYMENT_ADAPTERS as readonly string[]).includes(val);
}

export function isBuildTarget(val: string): val is BuildTarget {
  return (BUILD_TARGETS as readonly string[]).includes(val);
}

export type RedisSetupOption = 'docker' | 'existing' | 'none';
export type PackageManagerOption = 'npm' | 'yarn' | 'pnpm';

export interface ParsedArgs {
  _: string[];
  outDir?: string;
  entry?: string;
  help?: boolean;
  runInBand?: boolean;
  watch?: boolean;
  verbose?: boolean;
  timeout?: number;
  coverage?: boolean;
  // Build --target flag (unified build target)
  buildTarget?: BuildTarget;
  // Build --js flag (cli target: produce JS bundle instead of SEA binary)
  js?: boolean;
  // MCPB flags
  sea?: boolean;
  mergeFrom?: string;
  icon?: string;
  noDeterministic?: boolean;
  stageOnly?: boolean;
  // Create command flags
  yes?: boolean;
  target?: DeploymentAdapter;
  redis?: RedisSetupOption;
  cicd?: boolean;
  pm?: PackageManagerOption;
  // Socket command flags
  socket?: string;
  db?: string;
  background?: boolean;
  // Process Manager flags
  port?: number;
  force?: boolean;
  maxRestarts?: number;
  follow?: boolean;
  lines?: number;
  // `frontmcp dev` flags (issue #398)
  autoPort?: boolean;
  showConflict?: boolean;
  // Install flags
  registry?: string;
  // Create --nx flag
  nx?: boolean;
  // Issue #399 — `frontmcp dev` watch-aware stdio bridge
  stdio?: boolean;
  serve?: boolean;
  logFile?: string;
  bufferSize?: number;
  reloadDeadlineMs?: number;
  // Issue #400 — top-level config flag (forwarded from program.opts().config)
  config?: string;
  // Issue #400 — eject-mcp-config flags
  out?: string;
  dryRun?: boolean;
  // Issue #400 — skills install / export defaults via config
  provider?: 'claude' | 'codex';
  bundle?: 'recommended' | 'minimal' | 'full' | 'none';
  exportTarget?: 'cursor' | 'windsurf' | 'copilot';
}

/**
 * @deprecated Use commander-based parsing via {@link createProgram} instead.
 * Kept for backward compatibility and existing test coverage.
 */
export function parseArgs(argv: string[]): ParsedArgs {
  const out: ParsedArgs = { _: [] };
  for (let i = 0; i < argv.length; i++) {
    const a = argv[i];
    if (a === '--out-dir' || a === '-o') out.outDir = argv[++i];
    else if (a === '--entry' || a === '-e') out.entry = argv[++i];
    else if (a === '--help' || a === '-h') out.help = true;
    else if (a === '--runInBand' || a === '-i') out.runInBand = true;
    else if (a === '--watch' || a === '-w') out.watch = true;
    else if (a === '--verbose' || a === '-v') out.verbose = true;
    else if (a === '--timeout' || a === '-t') {
      const parsed = parseInt(argv[++i], 10);
      out.timeout = Number.isNaN(parsed) ? undefined : parsed;
    } else if (a === '--coverage' || a === '-c') out.coverage = true;
    // Create command flags
    else if (a === '--yes' || a === '-y') out.yes = true;
    else if (a === '--target') {
      const val = argv[++i];
      if (isDeploymentAdapter(val)) out.target = val;
      if (isBuildTarget(val)) out.buildTarget = val;
    } else if (a === '--redis') out.redis = argv[++i] as RedisSetupOption;
    else if (a === '--cicd') out.cicd = true;
    else if (a === '--no-cicd') out.cicd = false;
    else if (a === '--pm') out.pm = argv[++i] as PackageManagerOption;
    // Socket command flags
    else if (a === '--socket' || a === '-s') out.socket = argv[++i];
    else if (a === '--db') out.db = argv[++i];
    else if (a === '--background' || a === '-b') out.background = true;
    else if (a === '--js') out.js = true;
    // Process Manager flags
    else if (a === '--port' || a === '-p') {
      const parsed = parseInt(argv[++i], 10);
      out.port = Number.isNaN(parsed) ? undefined : parsed;
    } else if (a === '--force' || a === '-f') out.force = true;
    else if (a === '--max-restarts') {
      const parsed = parseInt(argv[++i], 10);
      out.maxRestarts = Number.isNaN(parsed) ? undefined : parsed;
    } else if (a === '--follow' || a === '-F') out.follow = true;
    else if (a === '--lines' || a === '-n') {
      const parsed = parseInt(argv[++i], 10);
      out.lines = Number.isNaN(parsed) ? undefined : parsed;
    }
    // Create --nx flag
    else if (a === '--nx') out.nx = true;
    // Install flags
    else if (a === '--registry') out.registry = argv[++i];
    else out._.push(a);
  }
  return out;
}
