from werkzeug.security import generate_password_hash

from src.auth import db


def _make_verified_user(email="a@b.c", password="password12"):
    db.init_schema()
    uid = db.create_user(email, generate_password_hash(password))
    db.set_email_verified(uid)
    return uid


def test_login_success(client, users_db_path):
    _make_verified_user()
    resp = client.post(
        "/auth/login",
        data={"email": "a@b.c", "password": "password12"},
    )
    assert resp.status_code == 302
    assert resp.headers["Location"].endswith("/compte/abonnement")


def test_login_wrong_password(client, users_db_path):
    _make_verified_user()
    resp = client.post(
        "/auth/login", data={"email": "a@b.c", "password": "wrong-password"}
    )
    assert "error=invalid_credentials" in resp.headers["Location"]


def test_login_unknown_email_same_error(client, users_db_path):
    db.init_schema()
    resp = client.post(
        "/auth/login",
        data={"email": "inexistant@example.com", "password": "x" * 12},
    )
    assert "error=invalid_credentials" in resp.headers["Location"]


def test_login_unverified_user(client, users_db_path):
    db.init_schema()
    db.create_user("a@b.c", generate_password_hash("password12"))
    resp = client.post("/auth/login", data={"email": "a@b.c", "password": "password12"})
    assert "error=email_not_verified" in resp.headers["Location"]


def test_login_respects_safe_next(client, users_db_path):
    _make_verified_user()
    resp = client.post(
        "/auth/login",
        data={"email": "a@b.c", "password": "password12", "next": "/tableau"},
    )
    assert resp.headers["Location"].endswith("/tableau")


def test_login_rejects_absolute_next(client, users_db_path):
    _make_verified_user()
    resp = client.post(
        "/auth/login",
        data={
            "email": "a@b.c",
            "password": "password12",
            "next": "https://evil.com",
        },
    )
    assert resp.headers["Location"].endswith("/compte/abonnement")


def test_logout_clears_session(client, users_db_path):
    _make_verified_user()
    client.post("/auth/login", data={"email": "a@b.c", "password": "password12"})
    resp = client.post("/auth/logout")
    assert resp.status_code == 302
    assert resp.headers["Location"].endswith("/")


# --- Tests CSRF (protection active, comme en production) ---


def test_login_rejects_missing_csrf_token(csrf_client):
    """POST /auth/login sans token CSRF → 400.

    Régression : avec prevent_initial_call=True sur _fill_csrf_inputs, le token
    n'était pas injecté dans le formulaire lors du chargement initial de /connexion.
    """
    resp = csrf_client.post(
        "/auth/login",
        data={"email": "a@b.c", "password": "password12"},
    )
    assert resp.status_code == 400


def test_login_accepts_valid_csrf_token(csrf_client, users_db_path):
    """POST /auth/login avec token CSRF valide → 302."""
    _make_verified_user()
    token = csrf_client.get("/_test/csrf").data.decode()
    resp = csrf_client.post(
        "/auth/login",
        data={"email": "a@b.c", "password": "password12", "csrf_token": token},
    )
    assert resp.status_code == 302
