import pytest
import json
from unittest.mock import patch
from app.schema.register import RegisterSchema 
from mongoengine import connect
from app.config.settings import TestingConfig

class TestAuthRegisterAPI:
    
    def test_home_endpoint(self,client):
        response = client.get('/')
        assert response.status_code == 200
        assert b'Welcome to the Authentication Service API' in response.data

    def test_register_with_no_data(self,client):
        response = client.post("/api/auth/register",json=None,content_type="application/json")
        assert response.status_code == 400

    def test_register_with_missing_required_value(self,client,user_model_factory):
        payload_user = json.loads(user_model_factory.to_json())
        print(payload_user['email'])
        payload = {
            "company_name":payload_user['company_name'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        response = client.post("/api/auth/register",json=payload,content_type="application/json")
        assert b"Company type is required." in response.data


    # @pytest.mark.skip
    def test_user_are_created(self,client,user_model_factory):
        payload_user = json.loads(user_model_factory.to_json())
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        response = client.post("/api/auth/register",json=payload,content_type="application/json")
        assert response.status_code == 201
        assert b"User registered successfully" in response.data
        # print(response.json)

    def test_register_endpoint_with_weak_password(self,client,user_model_weak_pass):
        payload_user = json.loads(user_model_weak_pass.to_json())
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        response = client.post("/api/auth/register",json=payload,content_type="application/json")
        assert response.status_code == 400


class TestLoginAPI:
    def test_login_with_wrong_request_method(self,client):

        response = client.get("/api/auth/register")
        assert response.status_code == 405

    def test_login_with_missing_password(self,client,user_model_login):
        payload_user = user_model_login
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        register = client.post("/api/auth/register",json=payload,content_type="application/json")
        
        response = client.post("/api/auth/login",
                               json={"email":payload_user['email']}
                               )
        
        assert response.status_code == 400

    def test_login_with_missing_email(self,client,user_model_login):
        payload_user = user_model_login
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        register = client.post("/api/auth/register",json=payload,content_type="application/json")
        
        response = client.post("/api/auth/login",
                               json={"password":payload_user['password']}
                               )
        
        assert response.status_code == 400
    
    def test_login_with_correct_data(self,client,user_model_login):
        payload_user = user_model_login
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        register = client.post("/api/auth/register",json=payload,content_type="application/json")
        
        response = client.post("/api/auth/login",
                               json={
                                   "email":payload_user['email'],
                                   "password":payload_user['password']
                                   }
                               )
        assert response.status_code == 200

        

        
class TestLogoutAPI:
    def test_logout_without_jwt(self,client):
        response = client.post("/api/auth/logout")
        assert b"Missing Authorization Header" in response.data
        assert response.status_code == 401


    def test_logout_with_jwt(self,client,user_model_login):
        payload_user = user_model_login
        payload = {
            "company_name":payload_user['company_name'],
            "company_type":payload_user['company_type'],
            "email":payload_user['email'],
            "username":payload_user['username'],
            "password":payload_user['password'],
            "password_confirm":payload_user['password']
            }
        register = client.post("/api/auth/register",json=payload,content_type="application/json")
        
        response = client.post("/api/auth/login",
                               json={"email":payload_user['email'],"password":payload_user['password']}
                               )
        # print("Access Token: ",response.json['token']['access'])
        headers = {
            'Authorization': f"Bearer {response.json['token']['access']}",
        }
        data = {
            "refresh": response.json['token']['refresh']
            }
        
        logout = client.post("/api/auth/logout",json=data,headers=headers,content_type="application/json")
        assert b"User logged out successfully" in logout.data
        assert logout.status_code == 200


class TestVerifyTokenAPI:
    def test_verify_token_api_without_token(self,client):
        response = client.post("/api/auth/token/verify",headers=None)
        assert response.status_code == 401
        assert b"Missing Authorization Header" in response.data

    def test_verify_token_are_valid(self,client,user_model_login):
        payload_user = user_model_login
        payload = {
            "company_name": payload_user['company_name'],
            "company_type": payload_user['company_type'],
            "email": payload_user['email'],
            "username": payload_user['username'],
            "password": payload_user['password'],
            "password_confirm": payload_user['password']
        }
        register = client.post("/api/auth/register", json=payload, content_type="application/json")

        response = client.post("/api/auth/login",
                               json={"email": payload_user['email'], "password": payload_user['password']}
                               )
        # print("Access Token: ",response.json['token']['access'])
        headers = {
            'Authorization': f"Bearer {response.json['token']['access']}",
        }
        data = {
            "refresh": response.json['token']['refresh']
        }
        verify = client.get("api/auth/token/verify",headers=headers)
        assert b"Token verified successfully." in verify.data



