"""
Augment CLI 辅助函数
用于调用Auggie CLI并管理Session Token
"""
import os
import subprocess
import json
import tempfile
from flask import session, g
from app.models.database.models import db
from app.models.database.base import get_beijing_now


def get_current_user_id():
    """获取当前用户ID"""
    # 尝试从g对象获取
    if hasattr(g, 'user') and g.user:
        return g.user.id if hasattr(g.user, 'id') else g.user.get('id')

    # 尝试从session获取
    if 'user_id' in session:
        return session['user_id']

    # 默认返回None
    return None


def get_user_augment_token(user_id=None):
    """
    获取用户的Augment Session Token
    如果用户没有设置自己的Token，则尝试使用全局Token
    
    从 AIProviderConfig 读取（统一存储方式）

    Args:
        user_id: 用户ID，如果为None则使用当前登录用户

    Returns:
        str: Token字符串，如果未设置则返回None
    """
    if user_id is None:
        user_id = get_current_user_id()

    if not user_id:
        return None

    # 从 AIProviderConfig 读取（统一存储方式）
    try:
        from app.models.database import AIProviderConfig
        # 优先读取用户的配置
        augment_config = AIProviderConfig.query.filter_by(
            user_id=user_id,
            provider_type='augment',
            is_active=True
        ).first()
        
        if augment_config:
            api_key = augment_config.get_api_key()
            if api_key and api_key.strip():
                # 更新最后使用时间
                augment_config.mark_used()
                return api_key.strip()
        
        # 如果没有用户配置，尝试读取全局配置（user_id 为 None）
        global_config = AIProviderConfig.query.filter_by(
            user_id=None,
            provider_type='augment',
            is_active=True,
            is_default=True
        ).first()
        
        if global_config:
            api_key = global_config.get_api_key()
            if api_key and api_key.strip():
                return api_key.strip()
    except Exception as e:
        # 如果读取失败，返回 None
        pass

    return None


def convert_token_to_augment_format(token_str):
    """
    将 Token 转换为 Augment CLI 期望的格式

    数据库中可能存储的格式:
    {"access_token": "...", "tenant_url": "...", ...}

    Augment CLI 期望的格式:
    {"accessToken": "...", "tenantURL": "...", "scopes": [...]}

    Args:
        token_str: Token JSON 字符串

    Returns:
        str: 转换后的 Token JSON 字符串
    """
    if not token_str:
        return None

    try:
        token_data = json.loads(token_str)

        # 检查是否已经是正确格式
        if 'accessToken' in token_data:
            return token_str

        # 转换格式
        converted = {}

        # access_token -> accessToken
        if 'access_token' in token_data:
            converted['accessToken'] = token_data['access_token']
        elif 'accessToken' in token_data:
            converted['accessToken'] = token_data['accessToken']

        # tenant_url -> tenantURL
        if 'tenant_url' in token_data:
            converted['tenantURL'] = token_data['tenant_url']
        elif 'tenantURL' in token_data:
            converted['tenantURL'] = token_data['tenantURL']
        else:
            converted['tenantURL'] = 'https://api.augmentcode.com/'

        # 保留 scopes
        if 'scopes' in token_data:
            converted['scopes'] = token_data['scopes']
        else:
            converted['scopes'] = ['read', 'write']

        return json.dumps(converted)
    except json.JSONDecodeError:
        return token_str


def call_auggie(instruction, user_id=None, **kwargs):
    """
    调用Auggie CLI执行指令

    Args:
        instruction: 要执行的指令
        user_id: 用户ID
        **kwargs: 其他Auggie参数
            - model: 模型名称
            - max_tokens: 最大令牌数
            - temperature: 温度
            - print_mode: 是否使用print模式 (默认True)
            - workspace_root: 工作空间根目录

    Returns:
        dict: {
            'success': bool,
            'output': str,
            'error': str
        }
    """
    token_str = get_user_augment_token(user_id)

    if not token_str:
        return {
            'success': False,
            'output': '',
            'error': 'Augment Session Token未设置，请先在个人中心设置Token'
        }

    # 解析Token JSON
    try:
        token_data = json.loads(token_str)
        access_token = token_data.get('accessToken') or token_data.get('access_token')
        tenant_url = token_data.get('tenantURL', 'https://api.augmentcode.com/')

        if not access_token:
            return {
                'success': False,
                'output': '',
                'error': 'Token格式错误: 缺少accessToken字段'
            }
    except json.JSONDecodeError:
        return {
            'success': False,
            'output': '',
            'error': 'Token格式错误: 不是有效的JSON'
        }

    # 构建命令
    cmd = ['auggie']

    # 添加指令
    cmd.append(instruction)

    # 添加参数
    if kwargs.get('print_mode', True):
        cmd.append('--print')

    if 'model' in kwargs:
        cmd.extend(['--model', kwargs['model']])

    if 'max_tokens' in kwargs:
        cmd.extend(['--max-tokens', str(kwargs['max_tokens'])])

    if 'temperature' in kwargs:
        cmd.extend(['--temperature', str(kwargs['temperature'])])

    if 'workspace_root' in kwargs:
        cmd.extend(['--workspace-root', kwargs['workspace_root']])

    # 创建临时文件存储Token (完整的JSON格式)
    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as f:
        f.write(token_str)
        token_file = f.name

    try:
        # 设置环境变量 (使用完整的Token JSON)
        env = os.environ.copy()
        env['AUGMENT_SESSION_AUTH'] = token_str
        
        # 执行命令
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            env=env,
            timeout=300  # 5分钟超时
        )
        
        return {
            'success': result.returncode == 0,
            'output': result.stdout,
            'error': result.stderr
        }
        
    except subprocess.TimeoutExpired:
        return {
            'success': False,
            'output': '',
            'error': '命令执行超时'
        }
    except Exception as e:
        return {
            'success': False,
            'output': '',
            'error': f'执行失败: {str(e)}'
        }
    finally:
        # 清理临时文件
        try:
            os.unlink(token_file)
        except:
            pass

def validate_augment_token(token_str):
    """
    验证Augment Token是否有效

    Args:
        token_str: Token字符串 (JSON格式)

    Returns:
        dict: {
            'valid': bool,
            'message': str,
            'token_info': dict (可选)
        }
    """
    try:
        # 解析JSON
        token_data = json.loads(token_str)

        # 检查必要字段 (支持两种格式)
        # 格式1: {"access_token": "...", ...}
        # 格式2: {"accessToken": "...", "tenantURL": "...", ...}
        has_access_token = 'access_token' in token_data
        has_accessToken = 'accessToken' in token_data

        if not has_access_token and not has_accessToken:
            return {
                'valid': False,
                'message': 'Token缺少必要字段: access_token 或 accessToken'
            }

        # 获取accessToken
        access_token = token_data.get('accessToken') or token_data.get('access_token')
        tenant_url = token_data.get('tenantURL', 'https://api.augmentcode.com/')

        # 验证Token格式
        if not access_token or len(access_token) < 32:
            return {
                'valid': False,
                'message': 'Token格式不正确'
            }

        # 实际验证Token是否有效 - 通过发送测试对话来验证
        try:
            # 创建临时指令文件
            test_instruction = "请回复'OK'来确认你收到了这条消息。"
            with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.md', encoding='utf-8') as f:
                f.write(test_instruction)
                instruction_file = f.name

            # 创建临时缓存目录（用于测试，避免污染用户的实际缓存）
            temp_cache_dir = tempfile.mkdtemp(prefix='augment_test_')

            try:
                # 设置环境变量
                env = os.environ.copy()
                env['AUGMENT_SESSION_AUTH'] = token_str

                # 使用auggie发送测试对话
                # 使用 -if (instruction file)、-p (print) 和 --augment-cache-dir 参数
                test_result = subprocess.run(
                    [
                        'auggie',
                        '-i', "请回复'OK'来确认你收到了这条消息。",
                        '-p',
                    ],
                    env=env,
                    timeout=30,  # 增加超时时间，因为需要实际调用API
                    capture_output=True,  # 捕获输出，不显示在控制台
                    text=True
                )
                print(test_result.stdout)
                if test_result.returncode == 0:
                    # Token有效，能够正常对话
                    return {
                        'valid': True,
                        'message': 'Token验证成功（已通过实际对话测试）',
                        'token_info': {
                            'scopes': token_data.get('scopes', []),
                            'tenant_url': tenant_url,
                            'test_response': test_result.stdout[:100] if test_result.stdout else ''
                        }
                    }
                else:
                    # Token无效或API调用失败
                    error_msg = test_result.stderr.strip() if test_result.stderr else 'Token验证失败'

                    # 检查是否是认证错误
                    if 'auth' in error_msg.lower() or 'token' in error_msg.lower() or 'unauthorized' in error_msg.lower():
                        return {
                            'valid': False,
                            'message': f'Token无效或已过期: {error_msg}'
                        }
                    else:
                        return {
                            'valid': False,
                            'message': f'Token验证失败: {error_msg}'
                        }

            finally:
                # 清理临时文件和目录
                try:
                    os.unlink(instruction_file)
                except:
                    pass

                try:
                    import shutil
                    shutil.rmtree(temp_cache_dir, ignore_errors=True)
                except:
                    pass

        except subprocess.TimeoutExpired:
            # 命令超时，可能是网络问题或API响应慢
            return {
                'valid': False,
                'message': 'Token验证超时（网络问题或API响应慢），请稍后重试'
            }
        except FileNotFoundError:
            # auggie CLI未安装
            return {
                'valid': False,
                'message': 'Auggie CLI未安装，无法验证Token。请先安装: npm install -g @augmentcode/cli'
            }
        except Exception as e:
            # 其他错误
            error_str = str(e)
            if 'auth' in error_str.lower() or 'token' in error_str.lower():
                return {
                    'valid': False,
                    'message': f'Token认证失败: {error_str}'
                }
            else:
                return {
                    'valid': False,
                    'message': f'Token验证出错: {error_str}'
                }

    except json.JSONDecodeError:
        return {
            'valid': False,
            'message': 'Token不是有效的JSON格式'
        }
    except Exception as e:
        return {
            'valid': False,
            'message': f'验证失败: {str(e)}'
        }
