from __future__ import annotations

import pytest
from fastapi import HTTPException
from fastapi.security import HTTPAuthorizationCredentials

from app.core.dependencies import get_current_user, require_admin, require_superuser
from app.core.security import create_access_token, hash_password
from app.modules.users.repository import create_user, update_user


def test_get_current_user_rejects_missing_credentials():
    with pytest.raises(HTTPException) as exc:
        get_current_user(None)
    assert exc.value.status_code == 401


def test_get_current_user_rejects_pending_user():
    user = create_user("pending-dep@example.com", hash_password("Valid123"), status="pending")
    token = create_access_token(user.id, user.role, user.is_superuser)
    credentials = HTTPAuthorizationCredentials(scheme="Bearer", credentials=token)
    with pytest.raises(HTTPException) as exc:
        get_current_user(credentials)
    assert exc.value.status_code == 403
    assert exc.value.detail == "EMAIL_NOT_VERIFIED"


def test_get_current_user_rejects_blocked_user():
    user = create_user("blocked-dep@example.com", hash_password("Valid123"), status="active")
    user.status = "blocked"
    update_user(user)
    token = create_access_token(user.id, user.role, user.is_superuser)
    credentials = HTTPAuthorizationCredentials(scheme="Bearer", credentials=token)
    with pytest.raises(HTTPException) as exc:
        get_current_user(credentials)
    assert exc.value.status_code == 403
    assert exc.value.detail == "ACCOUNT_BLOCKED"


def test_get_current_user_rejects_invalid_token():
    credentials = HTTPAuthorizationCredentials(scheme="Bearer", credentials="not-a-jwt")
    with pytest.raises(HTTPException) as exc:
        get_current_user(credentials)
    assert exc.value.status_code == 401
    assert exc.value.detail == "INVALID_TOKEN"


def test_get_current_user_rejects_unknown_user():
    token = create_access_token("missing-user-id", "user", False)
    credentials = HTTPAuthorizationCredentials(scheme="Bearer", credentials=token)
    with pytest.raises(HTTPException) as exc:
        get_current_user(credentials)
    assert exc.value.status_code == 401


def test_require_admin_rejects_regular_user():
    user = create_user("regular-dep@example.com", hash_password("Valid123"), role="user", status="active")
    with pytest.raises(HTTPException) as exc:
        require_admin(user)
    assert exc.value.status_code == 403


def test_require_superuser_rejects_non_super_admin():
    user = create_user("ops-dep@example.com", hash_password("Valid123"), role="admin", status="active")
    with pytest.raises(HTTPException) as exc:
        require_superuser(user)
    assert exc.value.status_code == 403
    assert exc.value.detail == "SUPERUSER_ONLY"
