# retoor <retoor@molodetz.nl>

import time

import requests

from devplacepy.database import (
    CONSENT_KINDS,
    consent_granted,
    get_table,
    refresh_snapshot,
)
from tests.conftest import BASE_URL

JSON = {"Accept": "application/json"}
_counter = [0]


def _unique(prefix="cons"):
    _counter[0] += 1
    return f"{prefix}{int(time.time() * 1000)}{_counter[0]}"


def _member():
    name = _unique()
    session = requests.Session()
    session.post(
        f"{BASE_URL}/auth/signup",
        data={
            "username": name,
            "email": f"{name}@t.dev",
            "password": "secret123",
            "confirm_password": "secret123",
            "birth_date": "1990-01-01",
            "accept_terms": "1",
        },
        allow_redirects=True,
    )
    refresh_snapshot()
    return session, name, get_table("users").find_one(username=name)


def test_the_privacy_tab_lists_every_consent(app_server):
    session, name, _ = _member()
    payload = session.get(
        f"{BASE_URL}/profile/{name}?tab=privacy", headers=JSON
    ).json()
    kinds = {entry["kind"] for entry in payload["consents"]}
    assert set(CONSENT_KINDS) == kinds
    states = {entry["kind"]: entry["state"] for entry in payload["consents"]}
    assert states["ai_third_party"] == "withdrawn"
    assert states["terms"] == "granted"


def test_granting_and_withdrawing_takes_effect_immediately(app_server):
    session, name, user = _member()
    granted = session.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "1"},
        headers=JSON,
    )
    assert granted.status_code == 200
    refresh_snapshot()
    assert consent_granted("user", user["uid"], "ai_third_party") is True

    withdrawn = session.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "0"},
        headers=JSON,
    )
    assert withdrawn.status_code == 200
    refresh_snapshot()
    assert consent_granted("user", user["uid"], "ai_third_party") is False


def test_consent_history_is_never_rewritten(app_server):
    session, name, user = _member()
    for granted in ("1", "0", "1"):
        session.post(
            f"{BASE_URL}/profile/{name}/consent",
            data={"kind": "ai_third_party", "granted": granted},
            headers=JSON,
        )
    refresh_snapshot()
    rows = list(
        get_table("user_consents").find(
            owner_kind="user", owner_id=user["uid"], kind="ai_third_party"
        )
    )
    assert len(rows) == 3


def test_an_unknown_consent_kind_is_refused(app_server):
    session, name, _ = _member()
    response = session.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "not_a_consent", "granted": "1"},
        headers=JSON,
    )
    assert response.status_code == 422


def test_the_gateway_refuses_user_content_without_consent(app_server):
    session, name, user = _member()
    refresh_snapshot()
    api_key = get_table("users").find_one(uid=user["uid"])["api_key"]
    headers = {**JSON, "Authorization": f"Bearer {api_key}"}
    body = {"model": "molodetz", "messages": [{"role": "user", "content": "hi"}]}

    refused = requests.post(
        f"{BASE_URL}/openai/v1/chat/completions", json=body, headers=headers
    )
    assert refused.status_code == 403
    assert "consent" in refused.text.lower()

    session.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "1"},
        headers=JSON,
    )
    allowed = requests.post(
        f"{BASE_URL}/openai/v1/chat/completions", json=body, headers=headers
    )
    assert allowed.status_code != 403


def _admin():
    session = requests.Session()
    session.post(
        f"{BASE_URL}/auth/login",
        data={"email": "alice@test.devplace", "password": "secret123"},
        allow_redirects=True,
    )
    return session


def test_an_admin_cannot_grant_a_consent_for_someone_else(app_server, seeded_db):
    _, name, user = _member()
    response = _admin().post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "1"},
        headers=JSON,
    )
    assert response.status_code == 403
    assert "account holder" in response.text
    refresh_snapshot()
    assert consent_granted("user", user["uid"], "ai_third_party") is False


def test_an_admin_cannot_withdraw_a_consent_for_someone_else(app_server, seeded_db):
    session, name, user = _member()
    session.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "1"},
        headers=JSON,
    )
    response = _admin().post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "0"},
        headers=JSON,
    )
    assert response.status_code == 403
    refresh_snapshot()
    assert consent_granted("user", user["uid"], "ai_third_party") is True


def test_an_admin_cannot_change_someone_elses_mature_preference(app_server, seeded_db):
    _, name, user = _member()
    before = get_table("users").find_one(uid=user["uid"])["mature_opt_in"]
    response = _admin().post(
        f"{BASE_URL}/profile/{name}/mature-content",
        data={"mature_opt_in": "1"},
        headers=JSON,
    )
    assert response.status_code == 403
    assert "account holder" in response.text
    refresh_snapshot()
    assert get_table("users").find_one(uid=user["uid"])["mature_opt_in"] == before


def test_a_stranger_cannot_change_another_members_consent(app_server):
    _, name, user = _member()
    stranger, _, _ = _member()
    response = stranger.post(
        f"{BASE_URL}/profile/{name}/consent",
        data={"kind": "ai_third_party", "granted": "1"},
        headers=JSON,
    )
    assert response.status_code == 403
    refresh_snapshot()
    assert consent_granted("user", user["uid"], "ai_third_party") is False


def test_the_mature_preference_round_trips(app_server):
    session, name, user = _member()
    response = session.post(
        f"{BASE_URL}/profile/{name}/mature-content",
        data={"mature_opt_in": "1"},
        headers=JSON,
    )
    assert response.status_code == 200
    refresh_snapshot()
    assert get_table("users").find_one(uid=user["uid"])["mature_opt_in"] in (1, True)
    session.post(
        f"{BASE_URL}/profile/{name}/mature-content",
        data={"mature_opt_in": "0"},
        headers=JSON,
    )
    refresh_snapshot()
    assert get_table("users").find_one(uid=user["uid"])["mature_opt_in"] in (0, False)
