import os
import json
from pathlib import Path
from typing import Dict, Any, Optional


class ClaudeSwitch:
    def __init__(self):
        self.config_dir = Path.home() / '.claude-switch'
        self.config_file = self.config_dir / 'config.json'
        self.env_file = self.config_dir / 'env.sh'
        self._ensure_config_dir()

    def _ensure_config_dir(self):
        """确保配置目录存在"""
        self.config_dir.mkdir(exist_ok=True)
        if not self.config_file.exists():
            self._create_default_config()

    def _create_default_config(self):
        """创建默认配置"""
        default_config = {
            "configs": {
                "default": {
                    "base_url": "https://api.anthropic.com",
                    "auth_token": "",
                    "api_key": "",
                    "note": "默认配置"
                }
            },
            "active": "default"
        }
        self._save_config(default_config)

    def _load_config(self) -> Dict[str, Any]:
        """加载配置"""
        try:
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            self._create_default_config()
            return self._load_config()

    def _save_config(self, config: Dict[str, Any]):
        """保存配置"""
        with open(self.config_file, 'w', encoding='utf-8') as f:
            json.dump(config, f, indent=2, ensure_ascii=False)
        os.chmod(self.config_file, 0o600)

    def list_configs(self) -> Dict[str, Dict[str, Any]]:
        """列出所有配置"""
        config = self._load_config()
        return config.get('configs', {})

    def get_current_config(self) -> Optional[str]:
        """获取当前激活的配置名"""
        config = self._load_config()
        return config.get('active')

    def get_config(self, name: str) -> Optional[Dict[str, Any]]:
        """获取指定配置"""
        configs = self.list_configs()
        return configs.get(name)

    def set_active(self, name: str) -> bool:
        """设置激活的配置"""
        config = self._load_config()
        if name not in config['configs']:
            return False
        
        config['active'] = name
        self._save_config(config)
        self._update_env_file()
        return True

    def add_config(self, name: str, base_url: str, auth_token: str, api_key: str, note: str) -> bool:
        """添加新配置"""
        if not name or not base_url:
            return False
        
        # 验证互斥逻辑
        if auth_token and api_key:
            return False
            
        config = self._load_config()
        config['configs'][name] = {
            'base_url': base_url,
            'auth_token': auth_token,
            'api_key': api_key,
            'note': note
        }
        self._save_config(config)
        return True

    def update_config(self, name: str, **kwargs) -> bool:
        """更新配置"""
        config = self._load_config()
        if name not in config['configs']:
            return False
            
        # 验证互斥逻辑
        auth_token = kwargs.get('auth_token', config['configs'][name]['auth_token'])
        api_key = kwargs.get('api_key', config['configs'][name]['api_key'])
        if auth_token and api_key:
            return False
            
        config['configs'][name].update(kwargs)
        self._save_config(config)
        
        # 如果更新的是当前激活的配置，需要更新环境文件
        if self.get_current_config() == name:
            self._update_env_file()
        
        return True

    def remove_config(self, name: str) -> bool:
        """删除配置"""
        config = self._load_config()
        if name not in config['configs']:
            return False
            
        if len(config['configs']) <= 1:
            return False  # 至少保留一个配置
            
        del config['configs'][name]
        
        # 如果删除的是当前激活的配置，切换到默认配置
        if config['active'] == name:
            config['active'] = next(iter(config['configs']))
            self._update_env_file()
            
        self._save_config(config)
        return True

    def _update_env_file(self):
        """更新环境变量文件"""
        current = self.get_current_config()
        if not current:
            return
            
        config = self.get_config(current)
        if not config:
            return

        with open(self.env_file, 'w') as f:
            f.write('# Claude Switch Environment Variables\n')
            f.write('# This file is auto-generated by claude-switch\n\n')
            f.write(f'export ANTHROPIC_BASE_URL="{config["base_url"]}"\n')
            f.write(f'export ANTHROPIC_AUTH_TOKEN="{config["auth_token"]}"\n')
            f.write(f'export ANTHROPIC_API_KEY="{config["api_key"]}"\n')

    def init_shell(self) -> str:
        """初始化shell集成"""
        shell_config_map = {
            'bash': '.bashrc',
            'zsh': '.zshrc',
            'fish': '.config/fish/config.fish'
        }
        
        shell = os.environ.get('SHELL', '').split('/')[-1]
        if shell not in shell_config_map:
            shell = 'bash'  # 默认bash
            
        shell_config = Path.home() / shell_config_map[shell]
        source_line = f'source {self.env_file}'
        
        try:
            if shell_config.exists():
                with open(shell_config, 'r') as f:
                    content = f.read()
                if source_line not in content:
                    with open(shell_config, 'a') as f:
                        f.write(f'\n# Claude Switch\n{source_line}\n')
                    return str(shell_config)
            else:
                # 创建配置文件
                with open(shell_config, 'w') as f:
                    f.write(f'\n# Claude Switch\n{source_line}\n')
                return str(shell_config)
        except Exception as e:
            return f"初始化失败: {e}"
        
        return "shell配置已存在"

    def format_config_display(self, name: str, config: Dict[str, Any]) -> str:
        """格式化配置显示"""
        auth_type = "auth_token" if config["auth_token"] else "api_key" if config["api_key"] else "未设置"
        masked_auth = "***" if config["auth_token"] or config["api_key"] else "无"
        return f"{name} - {config['note']} [{config['base_url']}] ({auth_type}: {masked_auth})"