from flask_bcrypt import Bcrypt
from flask import request
from flask_restx import Api, Namespace, Resource, fields
from flask_jwt_extended import jwt_required, get_jwt_identity, create_access_token, create_refresh_token
from flask import request
from app.models.user import User
from app import Config
from app.schema import user
import datetime
from flask_login import login_user
from app.utils import send_email
from decouple import config


bcrypt = Bcrypt()
# Create namespaces explicitly
auth_namespace = Namespace("auth", description="Authentication endpoints")

# initial database
users_collection =  Config.db['users']

# Define models using fields
login_model = auth_namespace.model(
    "Login",user.LOGIN_MODEL_FIELDS
    
)

api_register_model = auth_namespace.model(
    "User",user.USER_MODEL_FIELDS
    
)


@auth_namespace.route("/login")
class Login(Resource):

    @auth_namespace.expect(login_model, validate=True)
    @auth_namespace.doc(security=[])
    def post(self):
        """
        Authenticate a user
        """
 
        email = request.json.get("email", None)
        password = request.json.get("password", None)

        if not email or not password:
            return {
                "message": "Email and password are required"
            }, 400

        user = User.get_by_email(email=email)
        
        if not user or not bcrypt.check_password_hash(user['password'], password):
            return {
                "message": "Invalid email or password"
            }, 401
 
        return {
            "message": "Authenticated successfully", 
            "user": user['email'],
            "access": create_access_token(identity=email), 
            "refresh": create_refresh_token(identity=email)
        }, 200 
    
    
@auth_namespace.route('/register')
class Register(Resource):
    @auth_namespace.expect(api_register_model)
    @auth_namespace.doc(security=[])
    def post(self): 
        """
        User register with email and password and more attribute(s).
        """
        
        # store the json body request
        new_user = request.json
        print(new_user)
        existing_user = users_collection.find_one({'email': new_user['email']})
        
        # # check if user exist
        if existing_user:
            return {
                'status': False, 
                'message': 'Email already registered.'
            }, 409
        
        # #    
        if new_user['password'] != new_user['confirm_password']:
            return {
                'status': False, 
                'message': 'Passwords do not match'
            }, 400
        
        # new_user['password'] = bcrypt.hashpw(new_user['password'].encode('utf-8'), bcrypt.gensalt())
        
        # # 
        del new_user['confirm_password']
        
        
        # # Create User
        # users_collection.insert_one(new_user)
        # user_db = users_collection.find_one({'email':new_user['email']})
        # print("NEW USER: ",user_db)
        
        user_obj = User(
            username = new_user['username'],
            email = new_user['email'],
            password = bcrypt.generate_password_hash(new_user['password']).decode('utf-8'),
            is_verified = False
        )
        
        user_obj.save()
        


        # # Send Activation Email

        activation_token = user_obj.encode_auth_token(new_user['email'])
        # Implement your token creation logic
        activation_link = f'http://yourwebsite.com/activate/{activation_token}'
        

        send_email(
            subject='Activate Your Account', 
            sender_email= config('MAIL_USERNAME', default='', cast=str),
            recipient_email=[new_user['email']],
            body=f'Hello {new_user["last_name"]}, {new_user["first_name"]},\n\n'
                 f'Welcome to our platform! Please click the link below to activate your account:\n'
                 f'{activation_link}\n\n'
                 f'Thank you,\nThe Platform Team'
        ) 
        return ({
            'status': True, 
            'message': 'User created successfully'
        }, 201 )



# @auth.route("/logout")
# class Logout(Resource):
#     @jwt_required()
#     def post(self):
#         try:
#             current_user_id = get_jwt_identity()
#             jti = get_raw_jwt()['jti']

#             # Check if the token is already blacklisted
#             if BlacklistToken.is_blacklisted(jti):
#                 return {"message": "Token is already blacklisted"}, 400

#             # Add the current token to the blacklist with the current timestamp
#             BlacklistToken.add(jti, current_user_id)

#             # Return a response indicating successful logout
#             return {"message": "User logged out successfully"}, 200
#         except Exception as e:
#             # Handle any exceptions that may occur during the logout process
#             return {"message": "An error occurred during logout"}, 500
    

# @auth.route("/refresh-token")
# class RefreshToken(Resource):
#     @jwt_required(refresh=True)
#     def post(self):
#         # Implement refresh token logic here
#         return {"message": "Token refreshed successfully"}

# @auth.route("/verify-token")
# class VerifyToken(Resource):
#     @jwt_required()
#     def post(self):
#         # Implement verify token logic here
#         return {"message": "Token verified successfully"}

# @auth.route("/verify-email")
# class VerifyEmail(Resource):
#     def post(self):
#         # Implement verify email logic here
#         return {"message": "Email verified successfully"}

# @auth.route("/resend-verification-email")
# class ResendVerificationEmail(Resource):
#     def post(self):
#         # Implement resend verification email logic here
#         return {"message": "Verification email sent successfully"}

# @auth.route("/forget-password")
# class ForgetPassword(Resource):
#     def post(self):
#         # Implement forget password logic here
#         return {"message": "Password reset email sent successfully"}

# @auth.route("/reset-password")
# class ResetPassword(Resource):
#     def post(self):
#         # Implement reset password logic here
#         return {"message": "Password reset successfully"}