# _*_ coding : UTF-8 _*_
# @Time : 2025/01/18 02:13
# @UpdateTime : 2025/01/18 02:13
# @Author : sonder
# @File : response.py
# @Software : PyCharm
# @Comment : 本程序

from datetime import datetime
from typing import Any, Dict, Optional

from fastapi import status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse, StreamingResponse
from pydantic import BaseModel

from config.constant import HttpStatusConstant


class Response:
    """
    响应工具类，用于统一封装接口返回格式。
    """

    @classmethod
    def _build_response(
            cls,
            code: int,
            msg: str,
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
            success: bool = True,
    ) -> Dict:
        """
        构建统一的响应结果字典。

        :param code: 状态码
        :param msg: 响应消息
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :param success: 是否成功
        :return: 统一的响应结果字典
        """
        result = {
            "code": code,
            "msg": msg,
            "success": success,
            "time": datetime.now().isoformat(),  # 添加时间戳
        }

        # 添加可选字段
        if data is not None:
            result["data"] = data
        if rows is not None:
            result["rows"] = rows
        if dict_content is not None:
            result.update(dict_content)
        if model_content is not None:
            result.update(model_content.model_dump(by_alias=True))

        return result

    @classmethod
    def success(
            cls,
            msg: str = "操作成功",
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> JSONResponse:
        """
        成功响应方法。

        :param msg: 响应消息，默认为 "操作成功"
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :return: JSONResponse 对象
        """
        result = cls._build_response(
            code=HttpStatusConstant.SUCCESS,
            msg=msg,
            data=data,
            rows=rows,
            dict_content=dict_content,
            model_content=model_content,
            success=True,
        )
        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(result))

    @classmethod
    def failure(
            cls,
            msg: str = "操作失败",
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> JSONResponse:
        """
        失败响应方法。

        :param msg: 响应消息，默认为 "操作失败"
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :return: JSONResponse 对象
        """
        result = cls._build_response(
            code=400,
            msg=msg,
            data=data,
            rows=rows,
            dict_content=dict_content,
            model_content=model_content,
            success=False,
        )
        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(result))

    @classmethod
    def unauthorized(
            cls,
            msg: str = "登录信息已过期，访问系统资源失败",
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> JSONResponse:
        """
        未认证响应方法。

        :param msg: 响应消息，默认为 "登录信息已过期，访问系统资源失败"
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :return: JSONResponse 对象
        """
        result = cls._build_response(
            code=HttpStatusConstant.UNAUTHORIZED,
            msg=msg,
            data=data,
            rows=rows,
            dict_content=dict_content,
            model_content=model_content,
            success=False,
        )
        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(result))

    @classmethod
    def forbidden(
            cls,
            msg: str = "该用户无此接口权限",
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> JSONResponse:
        """
        未授权响应方法。

        :param msg: 响应消息，默认为 "该用户无此接口权限"
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :return: JSONResponse 对象
        """
        result = cls._build_response(
            code=HttpStatusConstant.FORBIDDEN,
            msg=msg,
            data=data,
            rows=rows,
            dict_content=dict_content,
            model_content=model_content,
            success=False,
        )
        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(result))

    @classmethod
    def error(
            cls,
            msg: str = "接口异常",
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> JSONResponse:
        """
        错误响应方法。

        :param msg: 响应消息，默认为 "接口异常"
        :param data: 响应数据
        :param rows: 响应行数据（通常用于分页）
        :param dict_content: 自定义字典内容
        :param model_content: 自定义 Pydantic 模型内容
        :return: JSONResponse 对象
        """
        result = cls._build_response(
            code=HttpStatusConstant.ERROR,
            msg=msg,
            data=data,
            rows=rows,
            dict_content=dict_content,
            model_content=model_content,
            success=False,
        )
        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(result))

    @classmethod
    def streaming(cls, data: Any) -> StreamingResponse:
        """
        流式响应方法。

        :param data: 流式传输的内容
        :return: StreamingResponse 对象
        """
        return StreamingResponse(content=data, status_code=status.HTTP_200_OK)
