import { createCommand } from '@trailhead/cli/command'
import { ok, err, createCoreError, type Result, type CoreError } from '@trailhead/core'
import { confirm, select, text } from '@trailhead/cli/prompts'
import { loadConfig, saveConfig } from '../lib/config.ts'
import type { Config } from '../lib/config-schema.ts'

/**
 * Configuration management command
 *
 * This is the default command that runs when no arguments are provided.
 * It displays the current configuration and allows interactive editing.
 */
export const configCommand = createCommand({
  name: 'config',
  description: 'View and edit application configuration',
  action: async (_options, context): Promise<Result<void, CoreError>> => {
    // Load current configuration
    const configResult = await loadConfig()
    if (configResult.isErr()) {
      context.logger.error(`Failed to load config: ${configResult.error.message}`)
      return err(configResult.error)
    }

    const config = configResult.value

    // Display current configuration
    context.logger.info('Current configuration:')
    context.logger.info('')
    context.logger.info(`  Name:        ${config.name}`)
    context.logger.info(`  Version:     ${config.version}`)
    context.logger.info(`  Environment: ${config.environment}`)
    context.logger.info(`  Theme color: ${config.theme.color}`)
    context.logger.info(`  Debug:       ${config.settings.debug}`)
    context.logger.info(`  Verbose:     ${config.settings.verbose}`)
    context.logger.info('')

    // Ask if user wants to edit
    const shouldEdit = await confirm({
      message: 'Would you like to edit the configuration?',
      default: false,
    })

    if (!shouldEdit) {
      return ok(undefined)
    }

    // Prompt for each configuration value
    const name = await text({
      message: 'Name:',
      initialValue: config.name,
      validate: (value) => (value && value.length > 0 ? undefined : 'Name is required'),
    })

    const version = await text({
      message: 'Version:',
      initialValue: config.version,
      validate: (value) =>
        value && /^\d+\.\d+\.\d+/.test(value) ? undefined : 'Version must be in semver format (e.g., 1.0.0)',
    })

    const environment = await select({
      message: 'Environment:',
      choices: [
        { name: 'Development', value: 'development' },
        { name: 'Production', value: 'production' },
        { name: 'Test', value: 'test' },
      ],
      default: config.environment,
    })

    const color = await select({
      message: 'Theme color:',
      choices: [
        { name: 'Blue', value: 'blue' },
        { name: 'Green', value: 'green' },
        { name: 'Red', value: 'red' },
        { name: 'Yellow', value: 'yellow' },
        { name: 'Magenta', value: 'magenta' },
        { name: 'Cyan', value: 'cyan' },
      ],
      default: config.theme.color,
    })

    const debug = await confirm({
      message: 'Enable debug mode?',
      default: config.settings.debug,
    })

    const verbose = await confirm({
      message: 'Enable verbose output?',
      default: config.settings.verbose,
    })

    // Create updated configuration
    const updatedConfig: Config = {
      name,
      version,
      environment: environment as Config['environment'],
      theme: {
        color: color as Config['theme']['color'],
      },
      settings: {
        debug,
        verbose,
      },
    }

    // Save configuration
    const saveResult = await saveConfig(updatedConfig)
    if (saveResult.isErr()) {
      context.logger.error(`Failed to save config: ${saveResult.error.message}`)
      return err(saveResult.error)
    }

    context.logger.success('Configuration saved successfully!')
    context.logger.info('')
    context.logger.info('Note: Restart the CLI to apply name/version changes')

    return ok(undefined)
  },
})
