"""Auth modülü testleri — happy path, çakışma, yetki, oturum revocation."""
import pytest

from tests.conftest import unique_email


@pytest.mark.asyncio
async def test_register_happy_path(client):
    email = unique_email()
    r = await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    assert r.status_code == 201
    body = r.json()
    assert body["success"] is True
    assert body["data"]["tenant"]["email"] == email
    assert body["data"]["tenant"]["plan"] == "free"
    assert body["data"]["tenant"]["api_key"].startswith("fvy_live_")
    assert body["data"]["token"]["access_token"]


@pytest.mark.asyncio
async def test_register_duplicate_email_conflict(client):
    email = unique_email()
    payload = {"name": "Test Co", "email": email, "password": "secret123"}
    await client.post("/api/auth/register", json=payload)
    r = await client.post("/api/auth/register", json=payload)
    assert r.status_code == 409
    assert r.json()["error"]["code"] == "CONFLICT"


@pytest.mark.asyncio
async def test_register_invalid_email_422(client):
    r = await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": "notanemail", "password": "secret123"},
    )
    assert r.status_code == 422
    assert r.json()["error"]["code"] == "VALIDATION_FAILED"


@pytest.mark.asyncio
async def test_login_and_me(client):
    email = unique_email()
    await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    r = await client.post(
        "/api/auth/login", json={"email": email, "password": "secret123"}
    )
    assert r.status_code == 200
    token = r.json()["data"]["token"]["access_token"]

    me = await client.get("/api/auth/me", headers={"Authorization": f"Bearer {token}"})
    assert me.status_code == 200
    assert me.json()["data"]["email"] == email


@pytest.mark.asyncio
async def test_login_wrong_password(client):
    email = unique_email()
    await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    r = await client.post(
        "/api/auth/login", json={"email": email, "password": "WRONG"}
    )
    assert r.status_code == 401
    assert r.json()["error"]["code"] == "UNAUTHORIZED"


@pytest.mark.asyncio
async def test_me_requires_auth(client):
    r = await client.get("/api/auth/me")
    assert r.status_code == 401


@pytest.mark.asyncio
async def test_logout_revokes_token(client):
    email = unique_email()
    reg = await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    token = reg.json()["data"]["token"]["access_token"]
    headers = {"Authorization": f"Bearer {token}"}

    assert (await client.get("/api/auth/me", headers=headers)).status_code == 200
    assert (await client.post("/api/auth/logout", headers=headers)).status_code == 204
    # revoked → 401
    r = await client.get("/api/auth/me", headers=headers)
    assert r.status_code == 401
    assert r.json()["error"]["code"] == "UNAUTHORIZED"


@pytest.mark.asyncio
async def test_change_password(client):
    email = unique_email()
    reg = await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    token = reg.json()["data"]["token"]["access_token"]
    headers = {"Authorization": f"Bearer {token}"}

    # yanlış mevcut şifre
    bad = await client.post(
        "/api/auth/change-password",
        headers=headers,
        json={"current_password": "WRONG", "new_password": "newsecret123"},
    )
    assert bad.status_code == 422

    ok = await client.post(
        "/api/auth/change-password",
        headers=headers,
        json={"current_password": "secret123", "new_password": "newsecret123"},
    )
    assert ok.status_code == 204

    # yeni şifre ile login
    r = await client.post(
        "/api/auth/login", json={"email": email, "password": "newsecret123"}
    )
    assert r.status_code == 200


@pytest.mark.asyncio
async def test_refresh_rotates_token(client):
    email = unique_email()
    reg = await client.post(
        "/api/auth/register",
        json={"name": "Test Co", "email": email, "password": "secret123"},
    )
    old = reg.json()["data"]["token"]["access_token"]
    headers = {"Authorization": f"Bearer {old}"}

    r = await client.post("/api/auth/refresh", headers=headers)
    assert r.status_code == 200
    new = r.json()["data"]["access_token"]
    assert new != old

    # eski token revoke edilmiş olmalı
    assert (await client.get("/api/auth/me", headers=headers)).status_code == 401
    # yeni token çalışmalı
    new_headers = {"Authorization": f"Bearer {new}"}
    assert (await client.get("/api/auth/me", headers=new_headers)).status_code == 200
