"""
操作日志服务层
"""
from typing import Optional, List, Dict, Any
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from app.crud.operation_log import operation_log_crud
from app.schemas.operation_log import OperationLogCreate


class OperationLogService:
    """操作日志服务类"""

    async def get_log(self, db: AsyncSession, log_id: int) -> Optional[Dict[str, Any]]:
        """
        获取操作日志详情

        Args:
            db: 数据库会话
            log_id: 日志ID

        Returns:
            日志信息
        """
        log = await operation_log_crud.get(db, log_id)
        if not log:
            return None

        return {
            "id": log.id,
            "operator_id": log.operator_id,
            "operator_name": log.operator_name,
            "operator_ip": log.operator_ip,
            "module": log.module,
            "operation_type": log.operation_type,
            "method": log.method,
            "url": log.url,
            "params": log.params,
            "result": log.result,
            "error_msg": log.error_msg,
            "duration": log.duration,
            "user_agent": log.user_agent,
            "extra_data": log.extra_data,
            "created_at": log.created_at,
            "action_type": log.operation_type,
            "path": log.url,
            "ip": log.operator_ip,
            "description": log.params,
            "operator": {"username": log.operator_name},
            "response": log.extra_data,
        }

    async def get_logs(
        self,
        db: AsyncSession,
        *,
        skip: int = 0,
        limit: int = 20,
        operator_id: Optional[int] = None,
        operator_name: Optional[str] = None,
        module: Optional[str] = None,
        operation_type: Optional[str] = None,
        result: Optional[str] = None,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None,
        keyword: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        获取操作日志列表

        Args:
            db: 数据库会话
            skip: 跳过条数
            limit: 返回条数
            operator_id: 操作人ID
            operator_name: 操作人姓名
            module: 模块名称
            operation_type: 操作类型
            result: 操作结果
            start_time: 开始时间
            end_time: 结束时间
            keyword: 关键词

        Returns:
            日志列表和总数
        """
        items, total = await operation_log_crud.get_multi(
            db,
            skip=skip,
            limit=limit,
            operator_id=operator_id,
            operator_name=operator_name,
            module=module,
            operation_type=operation_type,
            result=result,
            start_time=start_time,
            end_time=end_time,
            keyword=keyword
        )

        return {
            "items": [
                {
                    "id": item.id,
                    "operator_id": item.operator_id,
                    "operator_name": item.operator_name,
                    "operator_ip": item.operator_ip,
                    "module": item.module,
                    "operation_type": item.operation_type,
                    "method": item.method,
                    "url": item.url,
                    "result": item.result,
                    "error_msg": item.error_msg,
                    "duration": item.duration,
                    "created_at": item.created_at,
                    "action_type": item.operation_type,
                    "path": item.url,
                    "ip": item.operator_ip,
                    "description": item.params,
                    "operator": {"username": item.operator_name},
                    "user_agent": item.user_agent,
                    "response": item.extra_data,
                }
                for item in items
            ],
            "total": total
        }

    async def create_log(
        self,
        db: AsyncSession,
        obj_in: OperationLogCreate
    ) -> Dict[str, Any]:
        """
        创建操作日志

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

        Returns:
            创建的日志信息
        """
        import json

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

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

        log = await operation_log_crud.create(db, obj_in=obj_in_data)

        return {
            "id": log.id,
            "operator_name": log.operator_name,
            "module": log.module,
            "operation_type": log.operation_type,
        }

    async def get_statistics(
        self,
        db: AsyncSession,
        *,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None
    ) -> Dict[str, Any]:
        """
        获取操作日志统计信息

        Args:
            db: 数据库会话
            start_time: 开始时间
            end_time: 结束时间

        Returns:
            统计信息
        """
        return await operation_log_crud.get_statistics(
            db,
            start_time=start_time,
            end_time=end_time
        )

    async def get_operator_top(
        self,
        db: AsyncSession,
        *,
        limit: int = 10,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None
    ) -> List[Dict[str, Any]]:
        """
        获取操作排行榜

        Args:
            db: 数据库会话
            limit: 返回条数
            start_time: 开始时间
            end_time: 结束时间

        Returns:
            操作排行列表
        """
        return await operation_log_crud.get_operator_top(
            db,
            limit=limit,
            start_time=start_time,
            end_time=end_time
        )

    async def delete_old_logs(self, db: AsyncSession, *, days: int = 90) -> Dict[str, Any]:
        """
        删除旧日志

        Args:
            db: 数据库会话
            days: 保留天数

        Returns:
            删除结果
        """
        count = await operation_log_crud.delete_old_logs(db, days=days)
        return {
            "deleted_count": count,
            "message": f"已删除 {count} 条 {days} 天前的日志"
        }

    async def export_logs(
        self,
        db: AsyncSession,
        *,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None,
        operator_id: Optional[int] = None,
        module: Optional[str] = None,
        operation_type: Optional[str] = None
    ) -> List[Dict[str, Any]]:
        """
        导出操作日志

        Args:
            db: 数据库会话
            start_time: 开始时间
            end_time: 结束时间
            operator_id: 操作人ID
            module: 模块名称
            operation_type: 操作类型

        Returns:
            日志列表
        """
        items, total = await operation_log_crud.get_multi(
            db,
            skip=0,
            limit=10000,  # 导出限制
            operator_id=operator_id,
            module=module,
            operation_type=operation_type,
            start_time=start_time,
            end_time=end_time
        )

        return [
            {
                "操作人": item.operator_name,
                "模块": item.module,
                "操作类型": item.operation_type,
                "请求方法": item.method,
                "请求URL": item.url,
                "操作结果": item.result,
                "错误信息": item.error_msg or "",
                "执行时长(毫秒)": item.duration or 0,
                "操作时间": item.created_at.strftime("%Y-%m-%d %H:%M:%S"),
                "操作IP": item.operator_ip or "",
            }
            for item in items
        ]


# 创建全局实例
operation_log_service = OperationLogService()
