import pyotp
from jose import jwt
from sqlalchemy.orm import Session
from typing import Optional
from datetime import timedelta, datetime
from app.api.users.schemas import UserLoginForm
from libs.functions import md5
from libs.img_code import session
from models import users as users

SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM = "HS256"


def get_user(db, username: str):
    '''查询用户
    :param db: 模拟的数据库
    :param username: 用户名
    :return: 返回一个用户的BaseModel(其实就是字典的BaseModel对象,二者可互相转换)
    '''
    return db.query(users.User).filter(users.User.username == username).first()


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    '''创建tokens函数
    :param data: 对用JWT的Payload字段,这里是tokens的载荷,在这里就是用户的信息
    :param expires_delta: 缺省参数,截止时间
    :return:
    '''
    # 深拷贝data
    to_encode = data.copy()
    # 如果携带了截至时间,就单独设置tokens的过期时间
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        # 否则的话,就默认用15分钟
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({'exp': expire})
    # 编码,至此 JWT tokens诞生
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


def authenticate_user(db: Session, form_data: UserLoginForm):
    '''验证用户
    :param db: 存储用户的数据库
    :param username: 用户名
    :param password: 密码
    :param verify: 验证码
    :return:
    '''
    user_data = get_user(db=db, username=form_data.username)
    # 如果获取为空,返回False
    if not user_data:
        return {"result": False, "msg": "用户不存在"}
    # 如果密码不正确,也是返回False
    md5_password = md5(form_data.password)
    if md5_password != user_data.hashed_password:
        return {"result": False, "msg": "密码错误"}
    # 验证码检查
    if form_data.verify.lower() != session.headers.get("verify").lower():
        return {"result": False, "msg": "验证码错误"}
    if user_data.google_key:
        return {"result": True, "msg": "验证通过", "google_key": 1}
    else:
        return {"result": True, "msg": "验证通过", "google_key": 0}


def add_google_key(db: Session, user_id: int):
    updata = {
        "google_key": pyotp.random_base32(64),
        "update_time": datetime.now()
    }
    try:
        db.query(users.User).filter(users.User.id == user_id).update(updata)
        db.commit()
        return {"result": True, "google_key": updata.get("google_key")}
    except Exception as e:
        return {"result": False}