import pytest
from httpx import AsyncClient

from chitai.database import models as m


@pytest.mark.parametrize(
    ("email", "password", "expected_status_code"),
    [
        ("user1@example.com", "password123", 201),  # Valid credentials
        ("user1@example.com", "password234", 401),  # Invalid password
        ("user2@example.com", "password234", 201),  # Valid credentials
        ("user2@example.com", "password123", 401),  # Invalid password
        ("nonexistentUser@example.com", "password123", 401),  # Invalid email
    ],
)
async def test_user_login(
    client: AsyncClient, email: str, password: str, expected_status_code: int
) -> None:
    """Test login functionality with valid and invalid credentials."""

    response = await client.post(
        "/access/login", data={"email": email, "password": password}
    )

    assert response.status_code == expected_status_code

    if response.status_code == 201:
        result = response.json()
        assert result["access_token"] is not None


async def test_get_user_by_access_token(
    authenticated_client: AsyncClient, test_user: m.User
) -> None:
    """Test getting user info via their access token."""

    response = await authenticated_client.get("/access/me")
    assert response.status_code == 200

    result = response.json()
    assert result["email"] == test_user.email


async def test_get_user_without_access_token(client: AsyncClient) -> None:
    response = await client.get("/access/me")

    assert response.status_code == 401


async def test_user_registration_weak_password(client: AsyncClient) -> None:
    """Test user registration with a weak password."""

    response = await client.post(
        "/access/signup", json={"email": "weak@example.com", "password": "weak"}
    )

    assert response.status_code == 400

    msg = response.json()["extra"][0]["message"]
    assert "Password must be at least 8 characters long" in msg


async def test_user_registration(client: AsyncClient) -> None:
    """Test registering a new user and successfully loggin in."""

    user_data = {"email": "newuser@example.com", "password": "password123"}

    signup_response = await client.post("/access/signup", json=user_data)

    assert signup_response.status_code == 201

    # Login using the same credentials

    login_response = await client.post("/access/login", data=user_data)

    assert login_response.status_code == 201


async def test_user_registration_with_duplicate_email(client: AsyncClient) -> None:
    """Test registerig a new user using a duplicate email."""

    user_data = {"email": "user1@example.com", "password": "password12345"}

    response = await client.post("/access/signup", json=user_data)

    assert response.status_code == 409

    result = response.json()

    assert "A user with this email already exists" in result["detail"]
