import pytest

from src.auth.cookies import build_cookie_options
from src.auth.oidc import build_login_redirect_url
from src.auth.session import create_session_cookie, decode_session_cookie
from src.config import Settings


@pytest.mark.integration
def test_cookie_options_follow_environment_defaults(monkeypatch) -> None:
    monkeypatch.setenv("APP_ENV", "development")
    dev_settings = Settings()
    dev_options = build_cookie_options(dev_settings)

    monkeypatch.setenv("APP_ENV", "production")
    prod_settings = Settings()
    prod_options = build_cookie_options(prod_settings)

    assert dev_options["httponly"] is True
    assert dev_options["secure"] is False
    assert dev_options["samesite"] == "lax"
    assert prod_options["secure"] is True
    assert prod_options["samesite"] == "strict"


@pytest.mark.integration
def test_login_redirect_url_contains_required_oidc_params() -> None:
    settings = Settings()

    url = build_login_redirect_url(
        settings=settings,
        redirect_uri="http://localhost:8000/auth/callback",
        state="state-123",
    )

    assert "response_type=code" in url
    assert "client_id=headquarter-web" in url
    assert "scope=openid+profile+email" in url
    assert "state=state-123" in url


@pytest.mark.integration
def test_create_and_decode_session_cookie_round_trip() -> None:
    settings = Settings()
    user_id = "test-user-123"

    cookie = create_session_cookie(settings=settings, user_id=user_id)
    payload = decode_session_cookie(settings=settings, cookie_value=cookie)

    assert payload["user_id"] == user_id
    assert "exp" in payload


@pytest.mark.integration
def test_decode_session_rejects_invalid_signature() -> None:
    settings = Settings()
    other_settings = Settings(session_secret="different-secret")
    user_id = "test-user-123"

    cookie = create_session_cookie(settings=other_settings, user_id=user_id)

    with pytest.raises(ValueError, match="invalid session signature"):
        decode_session_cookie(settings=settings, cookie_value=cookie)


@pytest.mark.integration
def test_decode_session_rejects_expired_cookie(monkeypatch) -> None:
    settings = Settings(session_ttl_hours=-1)  # Already expired
    user_id = "test-user-123"

    cookie = create_session_cookie(settings=settings, user_id=user_id)

    with pytest.raises(ValueError, match="session expired"):
        decode_session_cookie(settings=settings, cookie_value=cookie)
