"""
正则规则 API 路由

提供正则规则的 CRUD 操作和导入导出功能
"""
from fastapi import APIRouter, HTTPException, UploadFile, File
from pydantic import BaseModel
from typing import List, Optional
import json
import logging

from services.regex_service import regex_service
from models.regex_rules import RegexRule, RegexRuleset, RegexScope
from services.system_settings_service import system_settings_service

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/regex", tags=["regex"])


# ==================== 数据模型 ====================

class RuleUpdateRequest(BaseModel):
    """规则更新请求"""
    rule: RegexRule
    scope: RegexScope
    name: Optional[str] = None  # 角色卡名称或预设名称（scope 为 CHARACTER/PRESET 时需要）


class SystemSettingsUpdate(BaseModel):
    """系统设置更新请求"""
    thinkingTagPrefix: Optional[str] = None
    thinkingTagSuffix: Optional[str] = None
    currentPresetName: Optional[str] = None


# ==================== 规则查询 ====================

@router.get("/rules")
async def get_rules(
    character_name: Optional[str] = None,
    preset_name: Optional[str] = None
):
    """
    获取适用的正则规则列表
    
    Args:
        character_name: 当前角色卡名称（可选）
        preset_name: 当前预设名称（可选）
    
    Returns:
        规则列表
    """
    try:
        rules = regex_service.get_rules_for_context(character_name, preset_name)
        return {
            "success": True,
            "rules": [rule.dict() for rule in rules],
            "count": len(rules)
        }
    except Exception as e:
        logger.error(f"获取规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/rulesets/global")
async def get_global_rulesets():
    """获取所有全局规则集"""
    try:
        rulesets = list(regex_service.global_rulesets.values())
        return {
            "success": True,
            "rulesets": [rs.dict() for rs in rulesets]
        }
    except Exception as e:
        logger.error(f"获取全局规则集失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/rulesets/character/{character_name}")
async def get_character_ruleset(character_name: str):
    """获取指定角色卡的规则集"""
    try:
        if character_name in regex_service.character_rulesets:
            ruleset = regex_service.character_rulesets[character_name]
            return {
                "success": True,
                "ruleset": ruleset.dict()
            }
        else:
            return {
                "success": True,
                "ruleset": None
            }
    except Exception as e:
        logger.error(f"获取角色规则集失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/rulesets/preset/{preset_name}")
async def get_preset_ruleset(preset_name: str):
    """获取指定预设的规则集"""
    try:
        if preset_name in regex_service.preset_rulesets:
            ruleset = regex_service.preset_rulesets[preset_name]
            return {
                "success": True,
                "ruleset": ruleset.dict()
            }
        else:
            return {
                "success": True,
                "ruleset": None
            }
    except Exception as e:
        logger.error(f"获取预设规则集失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 规则管理 ====================

@router.post("/rules")
async def add_rule(request: RuleUpdateRequest):
    """添加或更新规则"""
    try:
        # 获取现有的规则集
        existing_ruleset = None
        if request.scope == RegexScope.GLOBAL:
            # 对于全局作用域，查找是否已有同名规则集
            for ruleset_id, ruleset in regex_service.global_rulesets.items():
                if ruleset.name == request.rule.scriptName:
                    existing_ruleset = ruleset
                    break
        elif request.scope == RegexScope.CHARACTER and request.name:
            if request.name in regex_service.character_rulesets:
                existing_ruleset = regex_service.character_rulesets[request.name]
        elif request.scope == RegexScope.PRESET and request.name:
            if request.name in regex_service.preset_rulesets:
                existing_ruleset = regex_service.preset_rulesets[request.name]
        
        if existing_ruleset:
            # 如果已存在同名规则集，则更新其中的规则
            updated_rules = []
            rule_found = False
            for rule in existing_ruleset.rules:
                if rule.id == request.rule.id:
                    # 更新现有规则
                    updated_rules.append(request.rule)
                    rule_found = True
                else:
                    # 保留其他规则
                    updated_rules.append(rule)
            
            if not rule_found:
                # 如果没有找到相同ID的规则，则添加新规则
                updated_rules.append(request.rule)
            
            # 更新规则集
            existing_ruleset.rules = updated_rules
            regex_service.save_ruleset(existing_ruleset, request.scope, request.name)
        else:
            # 如果不存在同名规则集，则创建新的规则集
            new_ruleset = RegexRuleset(
                id=request.rule.id,
                name=request.rule.scriptName,
                rules=[request.rule]
            )
            regex_service.save_ruleset(new_ruleset, request.scope, request.name)
        
        # 重新加载规则
        regex_service._load_all_rules()
        
        return {
            "success": True,
            "message": "规则保存成功"
        }
    except Exception as e:
        logger.error(f"保存规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/rules/{rule_id}")
async def delete_rule(rule_id: str, scope: str = "global", name: Optional[str] = None):
    """
    删除规则
    
    Args:
        rule_id: 规则ID
        scope: 作用域 (global/character/preset)
        name: 角色名或预设名（scope 为 character/preset 时需要）
    """
    try:
        from models.regex_rules import RegexScope
        
        scope_map = {
            "global": RegexScope.GLOBAL,
            "character": RegexScope.CHARACTER,
            "preset": RegexScope.PRESET
        }
        scope_enum = scope_map.get(scope, RegexScope.GLOBAL)
        
        # 找到包含该规则的规则集
        if scope_enum == RegexScope.GLOBAL:
            rulesets = regex_service.global_rulesets
        elif scope_enum == RegexScope.CHARACTER:
            if not name:
                raise ValueError("删除角色规则需要提供角色名称")
            rulesets = {name: regex_service.character_rulesets.get(name)} if name in regex_service.character_rulesets else {}
        elif scope_enum == RegexScope.PRESET:
            if not name:
                raise ValueError("删除预设规则需要提供预设名称")
            rulesets = {name: regex_service.preset_rulesets.get(name)} if name in regex_service.preset_rulesets else {}
        
        # 查找并删除规则
        deleted = False
        for ruleset_name, ruleset in rulesets.items():
            if not ruleset:
                continue
            
            original_count = len(ruleset.rules)
            ruleset.rules = [r for r in ruleset.rules if r.id != rule_id]
            
            if len(ruleset.rules) < original_count:
                # 保存更新后的规则集
                regex_service.save_ruleset(ruleset, scope_enum, ruleset_name if scope_enum != RegexScope.GLOBAL else None)
                deleted = True
                break
        
        if not deleted:
            return {
                "success": False,
                "message": "未找到指定的规则"
            }
        
        # 重新加载规则
        regex_service._load_all_rules()
        
        return {
            "success": True,
            "message": "规则已删除"
        }
    except Exception as e:
        logger.error(f"删除规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 规则导入导出 ====================

@router.post("/import")
async def import_rules(file: UploadFile = File(...)):
    """
    导入正则规则（支持 SillyTavern 格式）- 文件上传方式
    
    可以导入：
    1. 单个规则文件（JSON 数组）
    2. 规则集文件（JSON 对象）
    """
    try:
        content = await file.read()
        data = json.loads(content.decode('utf-8'))
        
        # 判断格式并导入
        if isinstance(data, list):
            # SillyTavern 格式 - 导入为全局规则
            ruleset = regex_service._convert_sillytavern_format(data, file.filename.replace('.json', ''))
            regex_service.save_ruleset(ruleset, RegexScope.GLOBAL)
        elif isinstance(data, dict):
            if 'rules' in data:
                # 规则集格式
                ruleset = RegexRuleset(**data)
                regex_service.save_ruleset(ruleset, RegexScope.GLOBAL)
            else:
                raise ValueError("未知的文件格式")
        else:
            raise ValueError("无效的文件格式")
        
        # 重新加载规则
        regex_service._load_all_rules()
        
        return {
            "success": True,
            "message": f"成功导入规则集: {ruleset.name}"
        }
    except Exception as e:
        logger.error(f"导入规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/import-from-preset")
async def import_rules_from_preset(request: dict):
    """
    从预设导入正则规则 - JSON 数据方式
    
    Request Body:
    {
        "rules": [...],  // SillyTavern 格式的 regex_scripts 数组
        "scope": "preset",  // 作用域：global/character/preset
        "presetName": "预设名称"  // 当 scope 为 preset 时需要
    }
    """
    try:
        rules_data = request.get("rules", [])
        scope_str = request.get("scope", "global")
        preset_name = request.get("presetName")
        
        if not rules_data or not isinstance(rules_data, list):
            raise ValueError("无效的规则数据")
        
        # 转换作用域字符串为枚举
        scope_map = {
            "global": RegexScope.GLOBAL,
            "character": RegexScope.CHARACTER,
            "preset": RegexScope.PRESET
        }
        scope = scope_map.get(scope_str, RegexScope.GLOBAL)
        
        # 转换 SillyTavern 格式
        name = preset_name or "imported_rules"
        ruleset = regex_service._convert_sillytavern_format(rules_data, name, scope)
        
        # 保存规则集
        regex_service.save_ruleset(ruleset, scope, name)
        
        # 重新加载规则
        regex_service._load_all_rules()
        
        logger.info(f"✅ 从预设导入 {len(rules_data)} 条正则规则到 {scope.value}: {name}")
        
        return {
            "success": True,
            "message": f"成功导入 {len(rules_data)} 条正则规则",
            "rulesetId": ruleset.id
        }
    except Exception as e:
        logger.error(f"从预设导入规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/export/global")
async def export_global_rules():
    """导出所有全局规则"""
    try:
        all_rulesets = list(regex_service.global_rulesets.values())
        return {
            "success": True,
            "rulesets": [rs.dict() for rs in all_rulesets]
        }
    except Exception as e:
        logger.error(f"导出规则失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 系统设置 ====================

@router.get("/settings")
async def get_system_settings():
    """获取系统设置"""
    try:
        settings = system_settings_service.settings
        return {
            "success": True,
            "settings": settings.dict()
        }
    except Exception as e:
        logger.error(f"获取系统设置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/settings")
async def update_system_settings(request: SystemSettingsUpdate):
    """更新系统设置"""
    try:
        if request.thinkingTagPrefix is not None or request.thinkingTagSuffix is not None:
            prefix = request.thinkingTagPrefix or system_settings_service.settings.thinkingTagPrefix
            suffix = request.thinkingTagSuffix or system_settings_service.settings.thinkingTagSuffix
            system_settings_service.update_thinking_tags(prefix, suffix)
        
        if request.currentPresetName is not None:
            system_settings_service.update_current_preset(request.currentPresetName)
        
        return {
            "success": True,
            "message": "系统设置已更新"
        }
    except Exception as e:
        logger.error(f"更新系统设置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))
