# Example: be/tests/api/v1/test_auth.py
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.security import verify_password
from app.crud.user import get_user_by_email
from app.schemas.user import UserPublic # Import for response validation
from app.schemas.auth import Token # Import for response validation

pytestmark = pytest.mark.asyncio

async def test_signup_success(client: AsyncClient, db: AsyncSession):
    email = "testsignup@example.com"
    password = "testpassword123"
    response = await client.post(
        "/api/v1/auth/signup",
        json={"email": email, "password": password, "name": "Test Signup"},
    )
    assert response.status_code == 201
    data = response.json()
    assert data["email"] == email
    assert data["name"] == "Test Signup"
    assert "id" in data
    assert "created_at" in data
    # Verify password hash is NOT returned
    assert "password" not in data
    assert "hashed_password" not in data

    # Verify user exists in DB
    user_db = await get_user_by_email(db, email=email)
    assert user_db is not None
    assert user_db.email == email
    assert verify_password(password, user_db.hashed_password)


async def test_signup_email_exists(client: AsyncClient, db: AsyncSession):
    # Create user first
    email = "testexists@example.com"
    password = "testpassword123"
    await client.post(
        "/api/v1/auth/signup",
        json={"email": email, "password": password},
    )

    # Attempt signup again with same email
    response = await client.post(
        "/api/v1/auth/signup",
        json={"email": email, "password": "anotherpassword"},
    )
    assert response.status_code == 400
    assert "Email already registered" in response.json()["detail"]


async def test_login_success(client: AsyncClient, db: AsyncSession):
    email = "testlogin@example.com"
    password = "testpassword123"
    # Create user first via signup
    signup_res = await client.post(
        "/api/v1/auth/signup", json={"email": email, "password": password}
    )
    assert signup_res.status_code == 201

    # Attempt login
    login_payload = {"username": email, "password": password}
    response = await client.post("/api/v1/auth/login", data=login_payload) # Use data for form encoding
    assert response.status_code == 200
    data = response.json()
    assert "access_token" in data
    assert data["token_type"] == "bearer"
    # Optionally verify the token itself here using verify_access_token


async def test_login_wrong_password(client: AsyncClient, db: AsyncSession):
    email = "testloginwrong@example.com"
    password = "testpassword123"
    await client.post(
        "/api/v1/auth/signup", json={"email": email, "password": password}
    )

    login_payload = {"username": email, "password": "wrongpassword"}
    response = await client.post("/api/v1/auth/login", data=login_payload)
    assert response.status_code == 401
    assert "Incorrect email or password" in response.json()["detail"]
    assert "WWW-Authenticate" in response.headers
    assert response.headers["WWW-Authenticate"] == "Bearer"

async def test_login_user_not_found(client: AsyncClient, db: AsyncSession):
    login_payload = {"username": "nosuchuser@example.com", "password": "anypassword"}
    response = await client.post("/api/v1/auth/login", data=login_payload)
    assert response.status_code == 401
    assert "Incorrect email or password" in response.json()["detail"]