import json
import uuid
from datetime import datetime
from re import compile

from app import app, db
from Models import UserModel
from Models.AnalyticsModel import todays_analytics
from security.auth_server import verify
from Rest.UserRegex import *

username_re = compile('^' + get_username_regex() + '$')
display_name_re = compile('^' + get_display_name_regex() + '$')


def handle_auth_request(load):
    try:
        request = verify(load["request"], load["signature"])
        if request["name"] == "check_email":
            email = request["data"]["email"]
            exists = db.session.query(UserModel).filter(UserModel.email == email).first() is not None
            response = {"email_already_exists": exists}
            response = app.response_class(
                response=json.dumps(response, indent=4),
                status=200,
                mimetype='application/json'
            )
            return response

        elif request["name"] == "register":
            username = request["data"]["username"].lower()
            display_name = request["data"]["display_name"]
            password = request["data"]["password"]
            email = request["data"]["email"]
            if db.session.query(UserModel).filter(UserModel.email == email).first() is not None:
                response = {"success": False, "reason": "user already exists"}
            elif db.session.query(UserModel).filter(UserModel.username == username).first() is not None:
                response = {"success": False, "reason": "username already taken"}
            elif db.session.query(UserModel).count() >= 1000:
                response = {"success": False, "reason": "user limit reached"}
            elif not bool(username_re.match(username)):
                response = {"success": False, "reason": "invalid username"}
            elif not bool(display_name_re.match(display_name)):
                response = {"success": False, "reason": "invalid display_name"}
            else:
                new_user = UserModel.create(username=username, display_name=display_name, password=password, email=email)
                response = {"success": True, "data": {}}
                response["data"]["user_id"] = str(new_user.id)
                response["data"]["login_id"] = str(new_user.login_id)
                todays_analytics().register_count += 1
                db.session.commit()
            response = app.response_class(
                response=json.dumps(response, indent=4),
                status=200,
                mimetype='application/json'
            )
            return response

        elif request["name"] == "login":
            email = request["data"]["email"]
            password = request["data"]["password"]
            user = db.session.query(UserModel).filter(UserModel.email == email).first()
            if not user or not user.check_password(password):
                response = {"success": False, "reason": "login failed"}
            elif user.moderation_flags.is_banned():
                total_seconds = (user.moderation_flags.banned_till - datetime.utcnow()).total_seconds()
                seconds = int(total_seconds % 60)
                minutes = int(total_seconds / 60 % 60)
                hours = int(total_seconds / (60 * 60) % 24)
                days = int(total_seconds / (60 * 60 * 24))
                if days > 10000:
                    response = {"success": False, "reason": "banned", "banned_for": "permanent"}
                else:
                    response = {"success": False, "reason": "banned",
                                "banned_for": f"{days} days {hours} hours {minutes} minutes {seconds} seconds"}
            else:
                user_id = str(user.id)
                login_id = str(user.login_id)
                response = {"success": True, "data": {"user_id": user_id, "login_id": login_id}}
            response = app.response_class(
                response=json.dumps(response, indent=4),
                status=200,
                mimetype='application/json'
            )
            return response

        elif request["name"] == "check_login_id":
            user_id = request["data"]["user_id"]
            login_id = request["data"]["login_id"]
            user = db.session.query(UserModel).filter(UserModel.id == uuid.UUID(user_id)).first()
            if not user:
                check = False
            else:
                check = user.login_id == uuid.UUID(login_id)
            response = {"valid_login_id": check}
            response = app.response_class(
                response=json.dumps(response, indent=4),
                status=200,
                mimetype='application/json'
            )
            return response

        elif request["name"] == "set_new_password":
            email = request["data"]["email"]
            new_password = request["data"]["new_password"]
            user = db.session.query(UserModel).filter(UserModel.email == email).first()
            user.set_password(new_password)
            response = {"success": True}
            response = app.response_class(
                response=json.dumps(response, indent=4),
                status=200,
                mimetype='application/json'
            )
            return response

    except KeyError:
        response = app.response_class(
            response="{\n    'response': 'invalid token structure'\n}",
            status=400,
            mimetype='application/json'
        )
        return response
