from datetime import datetime, timedelta, timezone
from enum import StrEnum

import jwt

from config import settings
from schemas.auth import JWTPayload, JWTDecoder


class TokenType(StrEnum):
    ACCESS = "access"
    REFRESH = "refresh"


def create_access_token(token_type: TokenType, data: JWTPayload) -> str:
    payload = data.model_dump().copy()
    if token_type == TokenType.ACCESS:
        expire = datetime.now(settings.tz) + timedelta(
            days=settings.ACCESS_TOKEN_EXPIRE_DAYS
        )
    else:
        expire = datetime.now(settings.tz) + timedelta(
            days=settings.REFRESH_TOKEN_EXPIRE_DAYS
        )
    payload["type"] = token_type.value
    payload["exp"] = expire
    encoded_jwt = jwt.encode(payload, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
    return encoded_jwt


def verify_token(token: str, token_type: TokenType) -> JWTDecoder:
    payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
    if payload["type"] != token_type.value:
        raise jwt.InvalidTokenError("Token类型不匹配")

    # 1. 将JWT的UTC时间戳转换为UTC时区的datetime
    exp_utc = datetime.fromtimestamp(payload["exp"], tz=timezone.utc)
    # 2. 转换为全局配置的时区（如Asia/Shanghai）
    exp_time = exp_utc.astimezone(settings.tz)
    # 3. 获取当前全局时区时间
    current_time = datetime.now(settings.tz)

    if exp_time < current_time:
        raise jwt.ExpiredSignatureError("Token已过期")

    return JWTDecoder(**payload)
