import uuid
from fastapi import APIRouter
from fastapi.responses import JSONResponse
import bcrypt

from ..utils import MONGODB_DATABASE, mongodb_connect, encode_auth_token, decode_auth_token
from ..models.auth import Login, ResetPassword

mongodb_client = mongodb_connect()

router = APIRouter(
    prefix="/auth",
    tags=["auth"],
    responses={404: {"description": "Not found"}},
)


@router.post("/login")
async def login(login: Login):
    """ Login a user"""
    if login.email == "root":
        user_cursor = mongodb_client[MONGODB_DATABASE]["users"].find_one(
            {"login": login.email},
            {"_id": 0}
        )
    else:
        user_cursor = mongodb_client[MONGODB_DATABASE]["users"].find_one(
            {
                "email": login.email,
                "active": True,
            },
            {"_id": 0}
        )

    if not user_cursor:
        responseObject = {
            "status": "error",
            "endpoint": "Login",
            "message": "Erreur, l'utilisateu n'existe pas ou inactive",
        }
        return JSONResponse(content=responseObject, status_code=404)

    if user_cursor["verified"] == False:
        responseObject = {
            "status": "failed",
            "endpoint": "Login",
            "message": "Erreur, account not verified",
        }
        return JSONResponse(content=responseObject, status_code=401)

    if "hashed_password" not in user_cursor:
        responseObject = {
            "status": "failed",
            "endpoint": "Login",
            "message": "Erreur, réinitialisez votre mot de passe",
        }
        return JSONResponse(content=responseObject, status_code=401)

    if not bcrypt.checkpw(
        login.password.encode(
            "utf8"), user_cursor["hashed_password"].encode("utf-8")
    ):
        responseObject = {
            "status": "failed",
            "endpoint": "Login",
            "message": "Erreur, mot de passe incorrecte",
        }
        return JSONResponse(content=responseObject, status_code=401)
    auth_token = encode_auth_token(
        user_cursor["sub"], 3600 * 24 * 30)  # 30 days
    payload = decode_auth_token(auth_token)
    iat = payload["iat"]
    exp = payload["exp"]
    responseObject = {
        "status": "success",
        "message": "Authentification réussie.",
        "auth": auth_token,
        "sub": user_cursor["sub"],
        "roles": user_cursor["roles"],
        "timestamp": iat,
        "expiration": exp
    }
    if "site" in user_cursor:
        responseObject["site"] = user_cursor["site"]
    return responseObject


@router.post("/password/reset")
async def login(reset_password: ResetPassword):
    """Reset password"""
    try:
        user_cursor = mongodb_client[MONGODB_DATABASE]["users"].find_one(
            {"email": reset_password.email})
        if not user_cursor:
            responseObject = {
                "status": "error",
                "endpoint": "ResetPassword",
                "message": f"Erreur, l'utilisateur n'existe pas",
            }
            return JSONResponse(content=responseObject, status_code=404)

        salt = bcrypt.gensalt()

        hashed_password = bcrypt.hashpw(
            reset_password.password.encode("utf8"), salt)

        mongodb_client[MONGODB_DATABASE]["users"].update_one(
            {"email": reset_password.email},
            {"$set": {"hashed_password": hashed_password.decode("utf8")}}
        )
        responseObject = {
            "status": "success",
            "endpoint": "ResetPassword",
            "message": "Mot de passe réinitialisé avec succès."
        }
        return JSONResponse(content=responseObject, status_code=200)
    except Exception as e:
        responseObject = {
            "status": "error",
            "endpoint": "ResetPassword",
            "message": f"Erreur lors de la réinitialisation du mot de passe: {str(e)}"
        }
        return JSONResponse(content=responseObject, status_code=500)
