import datetime
from sqlalchemy.orm import Session
from fastapi import Depends, APIRouter, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError

from app.api.role.crud import get_id_to_authority
from app.api.users import crud
from app.api.users.login_verification import get_user
from core.config.env import env

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


def auth_token(token: str = Depends(oauth2_scheme)):
    try:
        # 解密tokens
        payload = jwt.decode(token, env.SECRET_KEY, algorithms=[env.ALGORITHM])
        # 从tokens的载荷payload中获取用户名
        username: str = payload.get('username')
        # 如果没有获取到,抛出异常
        if username is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='用户不存在')
        now_time = int(datetime.datetime.now().timestamp())
        if payload.get("exp") <= now_time:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='token过期')
        return token
    except JWTError as e:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f'{e}')


def get_current_user(db: Session, token: str = Depends(oauth2_scheme)):
    """
    获取当前用户信息,实际上是一个解密token的过程
    :param db: 数据模型
    :param token: 携带的token
    :return:
    """

    try:
        # 解密tokens
        payload = jwt.decode(token, env.SECRET_KEY, algorithms=[env.ALGORITHM])
        # 从tokens的载荷payload中获取用户名
        username: str = payload.get('username')
        user_data = get_user(db=db, username=username)
        user_info = crud.get_user_by_name(db, user_data.username)
        role_info = get_id_to_authority(db, user_info.role_id)
        auth_list = role_info.authority.split(',')
        json_data = {
            "username": user_data.username,
            "authority": [int(i) for i in auth_list],
            "type": 0 if '0' in auth_list else 1
        }
        return json_data
    except JWTError as e:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f'{e}')
