from flask_jwt_extended import decode_token
from pydantic import (
    BaseModel,
    StrictInt,
    validator,
    ValidationError,
    StrictBytes,
    UUID4,
)

from app.extensions.utils.log_helper import logger_
from core.domains.authentication.dto.auth_dto import GetBlacklistDto, GetVerificationDto
from core.exceptions import InvalidRequestException

logger = logger_.getLogger(__name__)


class GetBlacklistSchema(BaseModel):
    access_token: str
    user_id: StrictInt

    @validator("access_token")
    def check_access_token(cls, access_token):
        """
            allow_expired=False : 만료된 토큰 허용 안함
        """
        try:
            decode_token(access_token.encode("utf-8"))

        except Exception as e:
            logger.error(f"[GetBlacklistSchema][check_access_token] Error : {e}")
            raise ValidationError(f"[GetBlacklistSchema][check_access_token] error")

        return access_token


class GetJwtAllowedExpiredSchema(BaseModel):
    token: StrictBytes
    uuid: UUID4

    @validator("token")
    def check_token(cls, token):
        """
            decode_token() : 정상적인 JWT 라면 decode 가능
            -> allow_expired=True : 만료된 토큰도 decode 허용
            -> 토큰이 올바른 구조인지 체크
        """
        try:
            decode_token(token, allow_expired=True)

        except Exception as e:
            logger.error(f"[GetJwtAllowedExpiredSchema][check_token] Error : {e}")
            raise ValidationError(f"[GetJwtAllowedExpiredSchema][check_token] Error")

        return token

    @validator("uuid")
    def check_uuid(cls, uuid):
        return str(uuid)


class LogoutRequest:
    def __init__(self, access_token, user_id):
        self.access_token = access_token
        self.user_id = user_id

    def validate_request_and_make_dto(self):
        try:
            schema = GetBlacklistSchema(
                access_token=self.access_token, user_id=self.user_id
            ).dict()
            return GetBlacklistDto(**schema)
        except ValidationError as e:
            logger.error(f"[LogoutRequest][validate_request_and_make_dto] error : {e}")
            raise InvalidRequestException(message=e.errors())


class GetVerificationRequest:
    def __init__(self, token: bytes, uuid: str):
        self.token = token
        self.uuid = uuid

    def validate_request_and_make_dto(self):
        try:
            schema = GetJwtAllowedExpiredSchema(token=self.token, uuid=self.uuid).dict()
            return GetVerificationDto(**schema)
        except ValidationError as e:
            logger.error(
                f"[AllowedExpiredJwtTokenRequest][validate_request_and_make_dto] error : {e}"
            )
            raise InvalidRequestException(message=e.errors())
