import pytest
from flask import Flask
from api.auth_api import auth_api
from db.db import users_db
from tinydb import Query
from models.user import User
from werkzeug.security import generate_password_hash
from datetime import datetime, timedelta
import jwt
from tests.conftest import TEST_SECRET_KEY, TEST_REFRESH_TOKEN_EXPIRY_DAYS

@pytest.fixture
def client():
    app = Flask(__name__)
    app.register_blueprint(auth_api, url_prefix='/auth')
    app.config['TESTING'] = True
    app.config['SECRET_KEY'] = TEST_SECRET_KEY
    app.config['REFRESH_TOKEN_EXPIRY_DAYS'] = TEST_REFRESH_TOKEN_EXPIRY_DAYS
    with app.test_client() as client:
        yield client

def setup_marked_user(email, verified=False, verify_token=None, reset_token=None):
    users_db.remove(Query().email == email)
    user = User(
        first_name='Marked',
        last_name='User',
        email=email,
        password=generate_password_hash('password123'),
        verified=verified,
        marked_for_deletion=True,
        verify_token=verify_token,
        verify_token_created=datetime.utcnow().isoformat() if verify_token else None,
        reset_token=reset_token,
        reset_token_created=datetime.utcnow().isoformat() if reset_token else None
    )
    users_db.insert(user.to_dict())


def test_signup_marked_for_deletion(client):
    setup_marked_user('marked@example.com')
    data = {
        'first_name': 'Marked',
        'last_name': 'User',
        'email': 'marked@example.com',
        'password': 'password123'
    }
    response = client.post('/auth/signup', json=data)
    assert response.status_code == 403
    assert response.json['code'] == 'ACCOUNT_MARKED_FOR_DELETION'

def test_verify_marked_for_deletion(client):
    setup_marked_user('marked2@example.com', verify_token='verifytoken123')
    response = client.get('/auth/verify', query_string={'token': 'verifytoken123'})
    assert response.status_code == 400
    assert response.json['code'] == 'ACCOUNT_MARKED_FOR_DELETION'

def test_request_password_reset_marked_for_deletion(client):
    setup_marked_user('marked3@example.com')
    response = client.post('/auth/request-password-reset', json={'email': 'marked3@example.com'})
    assert response.status_code == 403
    assert response.json['code'] == 'ACCOUNT_MARKED_FOR_DELETION'

def test_me_marked_for_deletion(client):
    email = 'marked4@example.com'
    setup_marked_user(email, verified=True)
    
    # Get the user to access the ID
    user_dict = users_db.get(Query().email == email)
    user = User.from_dict(user_dict)
    
    # Create a valid JWT token for the marked user
    payload = {
        'email': email,
        'user_id': user.id,
        'token_version': user.token_version,
        'exp': datetime.utcnow() + timedelta(hours=24)
    }
    token = jwt.encode(payload, TEST_SECRET_KEY, algorithm='HS256')
    
    # Make request with token cookie
    client.set_cookie('access_token', token)
    response = client.get('/auth/me')
    
    assert response.status_code == 403
    assert response.json['code'] == 'ACCOUNT_MARKED_FOR_DELETION'
