"""
系统配置CRUD操作
"""
from typing import Optional, List, Dict, Any
from sqlalchemy import select, and_, or_, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.system_config import SystemConfig
import json


class SystemConfigCRUD:
    """系统配置CRUD类"""

    async def get(self, db: AsyncSession, config_id: int) -> Optional[SystemConfig]:
        """
        根据ID获取系统配置

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

        Returns:
            SystemConfig对象或None
        """
        result = await db.execute(
            select(SystemConfig).where(SystemConfig.id == config_id)
        )
        return result.scalar_one_or_none()

    async def get_by_key(self, db: AsyncSession, config_key: str) -> Optional[SystemConfig]:
        """
        根据配置键获取系统配置

        Args:
            db: 数据库会话
            config_key: 配置键

        Returns:
            SystemConfig对象或None
        """
        result = await db.execute(
            select(SystemConfig).where(SystemConfig.config_key == config_key)
        )
        return result.scalar_one_or_none()

    async def get_multi(
        self,
        db: AsyncSession,
        *,
        skip: int = 0,
        limit: int = 100,
        keyword: Optional[str] = None,
        category: Optional[str] = None,
        is_active: Optional[bool] = None,
        is_system: Optional[bool] = None
    ) -> tuple[List[SystemConfig], int]:
        """
        获取系统配置列表

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

        Returns:
            (配置列表, 总数)
        """
        # 构建查询条件
        conditions = []

        if keyword:
            conditions.append(
                or_(
                    SystemConfig.config_key.ilike(f"%{keyword}%"),
                    SystemConfig.config_name.ilike(f"%{keyword}%"),
                    SystemConfig.description.ilike(f"%{keyword}%")
                )
            )

        if category:
            conditions.append(SystemConfig.category == category)

        if is_active is not None:
            conditions.append(SystemConfig.is_active == is_active)

        if is_system is not None:
            conditions.append(SystemConfig.is_system == is_system)

        # 查询总数
        count_query = select(func.count(SystemConfig.id))
        if conditions:
            count_query = count_query.where(and_(*conditions))
        total_result = await db.execute(count_query)
        total = total_result.scalar() or 0

        # 查询数据
        query = select(SystemConfig)
        if conditions:
            query = query.where(and_(*conditions))
        query = query.order_by(SystemConfig.category, SystemConfig.sort_order, SystemConfig.id)
        query = query.offset(skip).limit(limit)

        result = await db.execute(query)
        items = result.scalars().all()

        return list(items), total

    async def get_by_category(
        self,
        db: AsyncSession,
        category: str,
        *,
        is_active: bool = True
    ) -> List[SystemConfig]:
        """
        根据分类获取配置列表

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

        Returns:
            配置列表
        """
        conditions = [SystemConfig.category == category]

        if is_active:
            conditions.append(SystemConfig.is_active == True)

        result = await db.execute(
            select(SystemConfig)
            .where(and_(*conditions))
            .order_by(SystemConfig.sort_order, SystemConfig.id)
        )
        return list(result.scalars().all())

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

        Args:
            db: 数据库会话

        Returns:
            分类列表
        """
        result = await db.execute(
            select(
                SystemConfig.category,
                func.count(SystemConfig.id).label('count')
            )
            .group_by(SystemConfig.category)
            .order_by(SystemConfig.category)
        )

        categories = []
        for row in result:
            categories.append({
                "category": row[0],
                "count": row[1]
            })

        return categories

    async def create(
        self,
        db: AsyncSession,
        *,
        obj_in: Dict[str, Any]
    ) -> SystemConfig:
        """
        创建系统配置

        Args:
            db: 数据库会话
            obj_in: 创建数据

        Returns:
            SystemConfig对象
        """
        db_obj = SystemConfig(**obj_in)
        db.add(db_obj)
        await db.flush()
        await db.refresh(db_obj)
        return db_obj

    async def update(
        self,
        db: AsyncSession,
        *,
        db_obj: SystemConfig,
        obj_in: Dict[str, Any]
    ) -> SystemConfig:
        """
        更新系统配置

        Args:
            db: 数据库会话
            db_obj: 数据库对象
            obj_in: 更新数据

        Returns:
            SystemConfig对象
        """
        for field, value in obj_in.items():
            if hasattr(db_obj, field):
                setattr(db_obj, field, value)

        await db.flush()
        await db.refresh(db_obj)
        return db_obj

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

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

        Returns:
            更新的配置列表
        """
        updated_configs = []

        for config_key, config_value in configs.items():
            db_obj = await self.get_by_key(db, config_key)
            if db_obj:
                # 转换为字符串存储
                if isinstance(config_value, (dict, list)):
                    config_value = json.dumps(config_value, ensure_ascii=False)
                elif isinstance(config_value, bool):
                    config_value = str(config_value).lower()
                else:
                    config_value = str(config_value)

                db_obj.config_value = config_value
                db_obj.updated_by = updater_id
                updated_configs.append(db_obj)

        await db.flush()
        return updated_configs

    async def delete(self, db: AsyncSession, *, config_id: int) -> Optional[SystemConfig]:
        """
        删除系统配置

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

        Returns:
            删除的SystemConfig对象或None
        """
        obj = await self.get(db, config_id)
        if obj:
            # 系统配置不允许删除
            if obj.is_system:
                raise ValueError("系统配置不允许删除")

            await db.delete(obj)
            await db.flush()
        return obj

    async def get_value(
        self,
        db: AsyncSession,
        config_key: str,
        default: Any = None
    ) -> Any:
        """
        获取配置值（自动转换类型）

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

        Returns:
            配置值
        """
        config = await self.get_by_key(db, config_key)
        if not config or not config.is_active:
            return default

        value = config.config_value

        # 根据类型转换
        if config.value_type == "boolean":
            return value.lower() in ("true", "1", "yes") if value else False
        elif config.value_type == "number":
            try:
                return int(value) if value else 0
            except ValueError:
                try:
                    return float(value) if value else 0.0
                except ValueError:
                    return 0
        elif config.value_type == "json":
            try:
                return json.loads(value) if value else {}
            except json.JSONDecodeError:
                return {}
        else:
            return value


# 创建全局实例
system_config_crud = SystemConfigCRUD()
