/**
 * DSS Config Command
 *
 * Manage DSS configuration.
 */

import chalk from 'chalk';
import {
  getConfig,
  loadProjectConfig,
  saveProjectConfig,
  setGlobalConfig,
  getGlobalConfig,
  listGlobalConfig,
  hasProjectConfig,
} from '../lib/config.js';

interface ConfigOptions {
  set?: string;
  get?: string;
  list?: boolean;
}

export async function configCommand(options: ConfigOptions): Promise<void> {
  if (options.set) {
    await setConfig(options.set);
  } else if (options.get) {
    await getConfigValue(options.get);
  } else if (options.list) {
    await listConfig();
  } else {
    await listConfig();
  }
}

async function setConfig(keyValue: string): Promise<void> {
  const [key, ...valueParts] = keyValue.split('=');
  const value = valueParts.join('=');

  if (!key || value === undefined) {
    console.log(chalk.red('  Invalid format. Use: --set key=value'));
    process.exit(1);
  }

  // Determine if this is a global or project config
  const globalKeys = ['figmaToken', 'defaultPort', 'defaultFormat'];
  const projectKeys = ['figmaFileKey', 'port', 'outputDir', 'tokenFormat', 'componentFramework'];

  if (globalKeys.includes(key)) {
    // Global config
    const parsedValue = parseValue(value);
    setGlobalConfig(key, parsedValue as string | number);
    console.log(chalk.green(`  Set global config: ${key}`));
    console.log(chalk.dim(`  Value: ${key === 'figmaToken' ? '***hidden***' : value}`));
  } else if (projectKeys.includes(key)) {
    // Project config
    if (!hasProjectConfig()) {
      console.log(chalk.yellow('  No project config found. Run: dss init'));
      process.exit(1);
    }

    const config = loadProjectConfig();
    (config as Record<string, unknown>)[key] = parseValue(value);
    saveProjectConfig(config);

    console.log(chalk.green(`  Set project config: ${key}`));
    console.log(chalk.dim(`  Value: ${value}`));
  } else {
    console.log(chalk.yellow(`  Unknown config key: ${key}`));
    console.log('');
    console.log(chalk.dim('  Global keys: figmaToken, defaultPort, defaultFormat'));
    console.log(chalk.dim('  Project keys: figmaFileKey, port, outputDir, tokenFormat, componentFramework'));
  }
}

async function getConfigValue(key: string): Promise<void> {
  const config = getConfig();
  const value = (config as Record<string, unknown>)[key];

  if (value === undefined) {
    // Try global config
    const globalValue = getGlobalConfig(key);
    if (globalValue !== undefined) {
      console.log(chalk.dim(`  ${key} (global):`), key === 'figmaToken' ? '***hidden***' : String(globalValue));
    } else {
      console.log(chalk.yellow(`  Config key not found: ${key}`));
    }
  } else {
    console.log(chalk.dim(`  ${key}:`), key === 'figmaToken' ? '***hidden***' : String(value));
  }
}

async function listConfig(): Promise<void> {
  console.log('');
  console.log(chalk.blue('  DSS Configuration'));
  console.log(chalk.dim('  ─────────────────'));
  console.log('');

  // Project config
  if (hasProjectConfig()) {
    console.log(chalk.green('  Project Config:'));
    const projectConfig = loadProjectConfig();
    Object.entries(projectConfig).forEach(([key, value]) => {
      console.log(chalk.dim(`    ${key}:`), String(value));
    });
  } else {
    console.log(chalk.yellow('  No project config (run: dss init)'));
  }

  console.log('');

  // Global config
  console.log(chalk.green('  Global Config:'));
  const globalConf = listGlobalConfig();
  Object.entries(globalConf).forEach(([key, value]) => {
    const displayValue = key === 'figmaToken' ? '***hidden***' : String(value);
    console.log(chalk.dim(`    ${key}:`), displayValue);
  });

  console.log('');

  // Merged config
  console.log(chalk.green('  Effective Config:'));
  const merged = getConfig();
  Object.entries(merged).forEach(([key, value]) => {
    const displayValue = key === 'figmaToken' ? (value ? '***configured***' : 'not set') : String(value);
    console.log(chalk.dim(`    ${key}:`), displayValue);
  });

  console.log('');
}

function parseValue(value: string): string | number | boolean {
  if (value === 'true') return true;
  if (value === 'false') return false;
  if (!isNaN(Number(value))) return Number(value);
  return value;
}
