"""
系统配置服务层
"""
from typing import Optional, List, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession
from app.crud.system_config import system_config_crud
from app.schemas.system_config import SystemConfigCreate, SystemConfigUpdate
import json


class SystemConfigService:
    """系统配置服务类"""

    async def get_config(self, db: AsyncSession, config_id: int) -> Optional[Dict[str, Any]]:
        """
        获取配置详情

        Args:
            db: 数据库会话
            config_id: 配置ID

        Returns:
            配置信息
        """
        config = await system_config_crud.get(db, config_id)
        if not config:
            return None

        return {
            "id": config.id,
            "config_key": config.config_key,
            "config_name": config.config_name,
            "config_value": config.config_value,
            "value_type": config.value_type,
            "category": config.category,
            "description": config.description,
            "is_system": config.is_system,
            "is_encrypted": config.is_encrypted,
            "validation_rule": config.validation_rule,
            "options": config.options,
            "default_value": config.default_value,
            "sort_order": config.sort_order,
            "is_active": config.is_active,
            "created_at": config.created_at,
            "updated_at": config.updated_at,
            "updated_by": config.updated_by,
        }

    async def get_config_by_key(
        self,
        db: AsyncSession,
        config_key: str,
        default: Any = None
    ) -> Any:
        """
        根据键获取配置值

        Args:
            db: 数据库会话
            config_key: 配置键
            default: 默认值

        Returns:
            配置值
        """
        return await system_config_crud.get_value(db, config_key, default)

    async def get_configs(
        self,
        db: AsyncSession,
        *,
        skip: int = 0,
        limit: int = 20,
        keyword: Optional[str] = None,
        category: Optional[str] = None,
        is_active: Optional[bool] = None,
        is_system: Optional[bool] = None
    ) -> Dict[str, Any]:
        """
        获取配置列表

        Args:
            db: 数据库会话
            skip: 跳过条数
            limit: 返回条数
            keyword: 搜索关键词
            category: 配置分类
            is_active: 是否启用
            is_system: 是否系统配置

        Returns:
            配置列表和总数
        """
        items, total = await system_config_crud.get_multi(
            db,
            skip=skip,
            limit=limit,
            keyword=keyword,
            category=category,
            is_active=is_active,
            is_system=is_system
        )

        return {
            "items": [
                {
                    "id": item.id,
                    "config_key": item.config_key,
                    "config_name": item.config_name,
                    "config_value": item.config_value,
                    "value_type": item.value_type,
                    "category": item.category,
                    "description": item.description,
                    "is_system": item.is_system,
                    "is_encrypted": item.is_encrypted,
                    "options": item.options,
                    "default_value": item.default_value,
                    "sort_order": item.sort_order,
                    "is_active": item.is_active,
                    "created_at": item.created_at,
                    "updated_at": item.updated_at,
                }
                for item in items
            ],
            "total": total
        }

    async def get_configs_by_category(
        self,
        db: AsyncSession,
        category: str,
        is_active: bool = True
    ) -> List[Dict[str, Any]]:
        """
        根据分类获取配置

        Args:
            db: 数据库会话
            category: 配置分类
            is_active: 是否启用

        Returns:
            配置列表
        """
        items = await system_config_crud.get_by_category(db, category, is_active=is_active)

        return [
            {
                "config_key": item.config_key,
                "config_name": item.config_name,
                "config_value": item.config_value,
                "value_type": item.value_type,
                "description": item.description,
            }
            for item in items
        ]

    async def get_categories(self, db: AsyncSession) -> List[Dict[str, Any]]:
        """
        获取所有配置分类

        Args:
            db: 数据库会话

        Returns:
            分类列表
        """
        return await system_config_crud.get_categories(db)

    async def create_config(
        self,
        db: AsyncSession,
        obj_in: SystemConfigCreate,
        creator_id: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        创建配置

        Args:
            db: 数据库会话
            obj_in: 创建数据
            creator_id: 创建人ID

        Returns:
            创建的配置信息
        """
        # 检查键是否已存在
        existing = await system_config_crud.get_by_key(db, obj_in.config_key)
        if existing:
            raise ValueError(f"配置键 {obj_in.config_key} 已存在")

        # 转换为字典
        obj_in_data = obj_in.model_dump()

        # 处理复杂类型
        if obj_in.options:
            obj_in_data["options"] = json.loads(obj_in.options.model_dump_json()) if isinstance(obj_in.options, dict) else obj_in.options

        config = await system_config_crud.create(db, obj_in=obj_in_data)

        return {
            "id": config.id,
            "config_key": config.config_key,
            "config_name": config.config_name,
            "category": config.category,
        }

    async def update_config(
        self,
        db: AsyncSession,
        config_id: int,
        obj_in: SystemConfigUpdate,
        updater_id: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        更新配置

        Args:
            db: 数据库会话
            config_id: 配置ID
            obj_in: 更新数据
            updater_id: 更新人ID

        Returns:
            更新的配置信息
        """
        config = await system_config_crud.get(db, config_id)
        if not config:
            raise ValueError("配置不存在")

        # 系统配置不允许修改某些字段
        if config.is_system:
            if obj_in.config_key and obj_in.config_key != config.config_key:
                raise ValueError("系统配置不允许修改配置键")
            if obj_in.value_type and obj_in.value_type != config.value_type:
                raise ValueError("系统配置不允许修改值类型")
            if obj_in.category and obj_in.category != config.category:
                raise ValueError("系统配置不允许修改分类")

        # 转换为字典，过滤None值
        update_data = obj_in.model_dump(exclude_unset=True)

        # 处理复杂类型
        if update_data.get("options"):
            update_data["options"] = json.loads(update_data["options"].model_dump_json()) if isinstance(update_data["options"], dict) else update_data["options"]

        update_data["updated_by"] = updater_id

        config = await system_config_crud.update(db, db_obj=config, obj_in=update_data)

        return {
            "id": config.id,
            "config_key": config.config_key,
            "config_name": config.config_name,
            "config_value": config.config_value,
        }

    async def batch_update_configs(
        self,
        db: AsyncSession,
        configs: Dict[str, Any],
        updater_id: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        批量更新配置

        Args:
            db: 数据库会话
            configs: 配置键值对
            updater_id: 更新人ID

        Returns:
            更新结果
        """
        updated = await system_config_crud.batch_update(
            db,
            configs=configs,
            updater_id=updater_id
        )

        return {
            "count": len(updated),
            "configs": [item.config_key for item in updated]
        }

    async def delete_config(self, db: AsyncSession, config_id: int) -> None:
        """
        删除配置

        Args:
            db: 数据库会话
            config_id: 配置ID
        """
        await system_config_crud.delete(db, config_id=config_id)


# 创建全局实例
system_config_service = SystemConfigService()
