#!/usr/bin/env python3

from flask import current_app, Flask, jsonify, request, Blueprint
from ..core.register_operations import RegisterOperations
from ..config import Config
from functools import wraps
from datetime import datetime, timedelta

from flask_httpauth import HTTPBasicAuth
import jwt

auth = HTTPBasicAuth()

config = Config().get_config()

register_routes = Blueprint("register_routes", __name__)
register_operation = RegisterOperations()

# Function to generate access tokens and refresh tokens
def generate_tokens(username):
    access_payload = {
        'username': username,
        'exp': datetime.now() + timedelta(minutes=config["register"]["token_expiration"])
    }
    refresh_payload = {
        'username': username,
        'exp': datetime.now() + timedelta(days=config["register"]["refresh_expiration"])
    }
    access_token = jwt.encode(access_payload, current_app.config['REGISTRE_SECRET_KEY'], algorithm='HS256')
    refresh_token = jwt.encode(refresh_payload, current_app.config['REGISTRE_SECRET_KEY'], algorithm='HS256')
    return access_token, refresh_token

# Function in charge of verifying the basic auth
@auth.verify_password
def verify_password(username, password):
    users = register_operation.get_users()[0].json["users"]
    if username in config["register"]["admin_users"] and password == config["register"]["admin_users"][username]:
        return username, "admin"
    for user in users:
        if user["username"] == username and user["password"]==password:
            return username, "client"

# Function responsible for verifying the token
def admin_required():
    def decorator(f):
        @wraps(f)
        def decorated(*args, **kwargs):
            
            token = request.headers.get('Authorization')
            if not token:
                return jsonify({'message': 'Token is missing'}), 401
            
            if token.startswith('Bearer '):
                token = token.split('Bearer ')[1]
            
            if not token:
                return jsonify({'message': 'Token is missing'}), 401

            try:
                data = jwt.decode(token, current_app.config['REGISTRE_SECRET_KEY'], algorithms=['HS256'], options={'verify_exp': True})
                username = data['username']
                return f(username, *args, **kwargs)
            except Exception as e:
                return jsonify({'message': str(e)}), 401

        return decorated
    return decorator

@register_routes.route('/login', methods=['POST'])
@auth.login_required
def login():
    username, rol = auth.current_user()
    if rol != "admin":
        return jsonify(message="Unauthorized. Administrator privileges required."), 401
    access_token, refresh_token = generate_tokens(username)
    return jsonify({'access_token': access_token, 'refresh_token': refresh_token})

@register_routes.route('/refresh', methods=['POST'])
@admin_required()
def refresh_token(username):
    access_token, _ = generate_tokens(username)
    return jsonify({'access_token': access_token})

@register_routes.route("/createUser", methods=["POST"])
@admin_required()
def register(username):
    username = request.json["username"]
    password = request.json["password"]
    description = request.json["description"]
    email = request.json["email"]

    return register_operation.register_user(username, password, description, email)

@register_routes.route("/getauth", methods=["GET"])
@auth.login_required
def getauth():
    username, _ = auth.current_user()
    return register_operation.get_auth(username)

@register_routes.route("/deleteUser/<uuid>", methods=["DELETE"])
@admin_required()
def remove(username, uuid):
    return register_operation.remove_user(uuid)


@register_routes.route("/getUsers", methods=["GET"])
@admin_required()
def getUsers(username):
    return register_operation.get_users()
