import {
  type BuildTarget,
  type DeploymentAdapter,
  type PackageManagerOption,
  type ParsedArgs,
  type RedisSetupOption,
} from './args';

/**
 * Convert commander's parsed command name, positional arguments, and options
 * into the {@link ParsedArgs} shape expected by existing handlers.
 */
export function toParsedArgs(
  commandName: string,
  positionalArgs: string[],
  options: Record<string, unknown>,
): ParsedArgs {
  const out: ParsedArgs = { _: [commandName, ...positionalArgs] };

  // General
  if (options['outDir'] !== undefined) out.outDir = options['outDir'] as string;
  if (options['entry'] !== undefined) out.entry = options['entry'] as string;

  // Build --target resolution
  if (commandName === 'build') {
    if (options['target'] !== undefined) out.buildTarget = options['target'] as BuildTarget;
    if (options['js'] !== undefined) out.js = options['js'] as boolean;
    if (options['sea'] !== undefined) out.sea = options['sea'] as boolean;
    if (options['mergeFrom'] !== undefined) out.mergeFrom = options['mergeFrom'] as string;
    if (options['icon'] !== undefined) out.icon = options['icon'] as string;
    if (options['deterministic'] === false) out.noDeterministic = true;
    if (options['stageOnly'] !== undefined) out.stageOnly = options['stageOnly'] as boolean;
  }

  // Create
  if (options['yes'] !== undefined) out.yes = options['yes'] as boolean;
  if (commandName === 'create' && options['target'] !== undefined) out.target = options['target'] as DeploymentAdapter;
  if (options['redis'] !== undefined) out.redis = options['redis'] as RedisSetupOption;
  if (options['cicd'] !== undefined) out.cicd = options['cicd'] as boolean;
  if (options['pm'] !== undefined) out.pm = options['pm'] as PackageManagerOption;
  if (options['nx'] !== undefined) out.nx = options['nx'] as boolean;

  // Test
  if (options['runInBand'] !== undefined) out.runInBand = options['runInBand'] as boolean;
  if (options['watch'] !== undefined) out.watch = options['watch'] as boolean;
  if (options['verbose'] !== undefined) out.verbose = options['verbose'] as boolean;
  if (options['timeout'] !== undefined) out.timeout = options['timeout'] as number;
  if (options['coverage'] !== undefined) out.coverage = options['coverage'] as boolean;

  // PM - start / socket
  if (options['port'] !== undefined) out.port = options['port'] as number;
  if (options['socket'] !== undefined) out.socket = options['socket'] as string;
  if (options['db'] !== undefined) out.db = options['db'] as string;
  if (options['background'] !== undefined) out.background = options['background'] as boolean;
  if (options['maxRestarts'] !== undefined) out.maxRestarts = options['maxRestarts'] as number;

  // PM - stop
  if (options['force'] !== undefined) out.force = options['force'] as boolean;

  // PM - logs
  if (options['follow'] !== undefined) out.follow = options['follow'] as boolean;
  if (options['lines'] !== undefined) out.lines = options['lines'] as number;

  // Package manager
  if (options['registry'] !== undefined) out.registry = options['registry'] as string;

  // Dev (issue #398): port conflict handling
  if (options['autoPort'] !== undefined) out.autoPort = options['autoPort'] as boolean;
  if (options['showConflict'] !== undefined) out.showConflict = options['showConflict'] as boolean;

  // Dev (issue #399): watch-aware stdio bridge
  if (options['stdio'] !== undefined) out.stdio = options['stdio'] as boolean;
  if (options['serve'] !== undefined) out.serve = options['serve'] as boolean;
  if (options['logFile'] !== undefined) out.logFile = options['logFile'] as string;
  if (options['bufferSize'] !== undefined) {
    out.bufferSize =
      typeof options['bufferSize'] === 'number' ? options['bufferSize'] : parseInt(String(options['bufferSize']), 10);
  }
  if (options['reloadDeadlineMs'] !== undefined) {
    out.reloadDeadlineMs =
      typeof options['reloadDeadlineMs'] === 'number'
        ? options['reloadDeadlineMs']
        : parseInt(String(options['reloadDeadlineMs']), 10);
  }

  // Issue #400 — top-level --config flag forwarded from program.opts()
  if (options['config'] !== undefined) out.config = options['config'] as string;
  // Issue #400 — eject-mcp-config
  if (options['out'] !== undefined) out.out = options['out'] as string;
  if (options['dryRun'] !== undefined) out.dryRun = options['dryRun'] as boolean;
  // Issue #400 — skills install/export defaults via config (still allow CLI override)
  if (options['provider'] !== undefined) out.provider = options['provider'] as 'claude' | 'codex';
  if (options['bundle'] !== undefined) {
    out.bundle = options['bundle'] as 'recommended' | 'minimal' | 'full' | 'none';
  }
  if (options['exportTarget'] !== undefined) {
    out.exportTarget = options['exportTarget'] as 'cursor' | 'windsurf' | 'copilot';
  }

  return out;
}
