from enum import Enum

from algo_backend.config import ErrorCodeConfig


def add_service_prefix(v: int):
    """
    对于失败的状态码，添加服务号码前缀
    """
    v_str = str(v)
    if len(v_str) == 8:
        return v
    if v is not None and v != 0 and ErrorCodeConfig.SERVICE_PREFIX:
        v = int(f"{ErrorCodeConfig.SERVICE_PREFIX}{v_str}")
    return v


class BasicStatusCode(Enum):
    def __new__(cls, value: int, msg: str):
        assert 0 <= value <= 999999, f"错误码长度不能超过6位，且非负数，{value}"
        obj = object.__new__(cls)
        obj._value_ = obj
        obj._code = value
        obj.msg = msg
        return obj

    @property
    def code(self):
        return add_service_prefix(self._code)

    @property
    def value(self):
        return self.code


class CommonStatusCode(BasicStatusCode):
    SUCCESS = (0, "成功")

    ERROR_REQ_URL = (400001, "请求路径错误")
    ERROR_REQ_METHOD = (400002, "{url}请求方法错误")
    BODY_EMPTY_ERR = (400003, "{url}请求体内容为空")
    PARAM_ERROR = (400006, "接口{url}参数错误,{msg}")
    ERROR_HEADER_NOW_EXISTS = (400007, "接口{url}缺少请求头:{header}")

    UNKNOWN_ERROR = (500000, "未知错误: {msg}")


class BasicApiId(Enum):
    """
    接口编号枚举类
    """

    def __new__(cls, value: int):
        assert 0 <= value <= 999, f"接口编号长度不能超过3位，且非负数，{value}"
        obj = object.__new__(cls)
        obj._value_ = obj
        obj.code = value
        return obj

    @property
    def value(self):
        return self.code

    def bind_api(self):
        """
        装饰器，绑定绑定api id
        """

        def decorator(enum_class):
            enum_class.__api_id__ = self
            return enum_class

        return decorator


class DefaultApiErrorCode(BasicApiId):
    """
    0表示不提供任何ApiId
    """

    DEFAULT_ERROR = 0


class BasicApiInnerErrorCode(Enum):
    def __new__(cls, value: int, msg: str):
        assert 1 <= value <= 99, f"接口内部错误码长度不能超过2位，且为正数，{value}"
        obj = object.__new__(cls)
        obj._value_ = obj
        obj.code = value
        obj.msg = msg
        return obj

    @property
    def value(self):
        return self.code

    @classmethod
    def gen_standard_code(cls, api_id: BasicApiId, inner_error_code: int = 0):
        """
        拼接并生成6位错误码
        """
        api_id = api_id or DefaultApiErrorCode.DEFAULT_ERROR
        return 500000 + api_id.code * 100 + inner_error_code
