import { readFileSync, writeFileSync, existsSync } from 'fs';
import { homedir } from 'os';
import { join } from 'path';
import { ToolError } from './errors';
import { execSync } from 'child_process';

export interface ToolConfig {
  defaultModel?: string;
  defaultOneshotModel?: string;
  defaultOneshotcatModel?: string;
  anthropicApiKey?: string;
  openaiApiKey?: string;
  modelAliases?: { [key: string]: string };
}

export const RC_FILE = '.meldrc';

function resolveSecretReference(value: string): string {
  if (!value.startsWith('op://')) {
    return value;
  }

  try {
    return execSync(`op read "${value}"`, { encoding: 'utf-8' }).trim();
  } catch (error: any) {
    throw new ToolError(
      `Failed to resolve 1Password secret reference: ${error.message}`,
      'SECRET_REFERENCE_ERROR'
    );
  }
}

export function loadConfig(options?: Partial<ToolConfig>): ToolConfig {
  // Start with empty config
  const config: ToolConfig = {};

  // Try to load .meldrc from home directory (lowest priority)
  try {
    const rcPath = join(homedir(), RC_FILE);
    if (existsSync(rcPath)) {
      const rcContent = readFileSync(rcPath, 'utf-8');
      const rcConfig = JSON.parse(rcContent);

      // Resolve any secret references in the config
      if (rcConfig.anthropicApiKey) {
        rcConfig.anthropicApiKey = resolveSecretReference(rcConfig.anthropicApiKey);
      }
      if (rcConfig.openaiApiKey) {
        rcConfig.openaiApiKey = resolveSecretReference(rcConfig.openaiApiKey);
      }

      Object.assign(config, rcConfig);
    }
  } catch (error) {
    if (error instanceof ToolError) {
      throw error; // Re-throw our own errors
    }
    // Ignore other errors reading config file - it's optional
  }

  // Load from environment variables (middle priority)
  if (process.env.DEFAULT_MODEL) {
    config.defaultModel = process.env.DEFAULT_MODEL;
  }
  if (process.env.ANTHROPIC_API_KEY) {
    config.anthropicApiKey = process.env.ANTHROPIC_API_KEY;
  }
  if (process.env.OPENAI_API_KEY) {
    config.openaiApiKey = process.env.OPENAI_API_KEY;
  }

  // Override with any passed options (highest priority)
  if (options) {
    // Only override values that are explicitly set in options
    Object.keys(options).forEach(key => {
      const value = options[key as keyof ToolConfig];
      if (value !== undefined) {
        (config as any)[key] = value;
      }
    });
  }

  return config;
}

export function setupConfig(options: {
  anthropicApiKey?: string;
  openaiApiKey?: string;
  defaultModel?: string;
  defaultOneshotModel?: string;
  defaultOneshotcatModel?: string;
  modelAliases?: { [key: string]: string };
}): void {
  // Don't create config if no options provided
  if (Object.keys(options).length === 0) {
    return;
  }

  const rcPath = join(homedir(), RC_FILE);
  let config: ToolConfig = {};

  // Read existing config if it exists
  if (existsSync(rcPath)) {
    try {
      const rcContent = readFileSync(rcPath, 'utf-8');
      config = JSON.parse(rcContent);
    } catch (error) {
      // If file exists but is invalid, we'll overwrite it
      console.warn('⚠️  Existing config file is invalid, creating new one');
    }
  }

  // Set default model aliases if none exist
  if (!config.modelAliases) {
    config.modelAliases = {
      'claude': 'claude-3-5-sonnet-latest',
      'sonnet': 'claude-3-5-sonnet-latest',
      'opus': 'claude-3-opus-latest',
      'haiku': 'claude-3-5-haiku-latest',
      '4o': 'chatgpt-4o-latest',
      'o1': 'o1',
      'o1-mini': 'o1-mini'
    };
  }

  // Set default models if not set
  if (!config.defaultOneshotModel) {
    config.defaultOneshotModel = 'claude-3-5-sonnet-latest';
  }
  if (!config.defaultOneshotcatModel) {
    config.defaultOneshotcatModel = 'claude-3-opus-latest';
  }

  // Update config with new values
  if (options.anthropicApiKey) config.anthropicApiKey = options.anthropicApiKey;
  if (options.openaiApiKey) config.openaiApiKey = options.openaiApiKey;
  if (options.defaultModel) config.defaultModel = options.defaultModel;
  if (options.defaultOneshotModel) config.defaultOneshotModel = options.defaultOneshotModel;
  if (options.defaultOneshotcatModel) config.defaultOneshotcatModel = options.defaultOneshotcatModel;
  if (options.modelAliases) {
    config.modelAliases = {
      ...config.modelAliases,
      ...options.modelAliases
    };
  }

  // Write config file
  writeFileSync(rcPath, JSON.stringify(config, null, 2));
}

export function checkAndPromptConfig(models: string[]): void {
  const config = loadConfig();
  const rcPath = join(homedir(), RC_FILE);
  const needsAnthropicKey = models.some(m => m.startsWith('claude')) && !config.anthropicApiKey;
  const needsOpenAIKey = models.some(m => m.startsWith('gpt')) && !config.openaiApiKey;

  if (!needsAnthropicKey && !needsOpenAIKey) {
    return; // All required keys are present
  }

  console.log('\n⚠️  Missing API key configuration');
  console.log('--------------------------------');
  
  if (needsAnthropicKey) {
    console.log('• Anthropic API key required for Claude models');
  }
  if (needsOpenAIKey) {
    console.log('• OpenAI API key required for GPT models');
  }

  console.log('\nTo configure your API keys, use:');
  if (needsAnthropicKey) {
    console.log('  meld-config --anthropic-key <your-key>');
  }
  if (needsOpenAIKey) {
    console.log('  meld-config --openai-key <your-key>');
  }

  console.log('\nOr use 1Password CLI secret references in .meldrc:');
  console.log('  {');
  if (needsAnthropicKey) {
    console.log('    "anthropicApiKey": "op://vault-name/anthropic/api-key"');
  }
  if (needsOpenAIKey) {
    console.log('    "openaiApiKey": "op://vault-name/openai/api-key"');
  }
  console.log('  }');

  console.log('\nOr set environment variables:');
  if (needsAnthropicKey) {
    console.log('  export ANTHROPIC_API_KEY=<your-key>');
  }
  if (needsOpenAIKey) {
    console.log('  export OPENAI_API_KEY=<your-key>');
  }

  console.log(`\nConfiguration will be saved to: ${rcPath}`);
  console.log('\nFor more options, run: meld-config --help');

  // Exit with error
  throw new ToolError('API keys required', 'MISSING_API_KEYS');
} 