"""
Statistiques admin enrichies (spec « Stratégie LLM par abonnement ») :
revenus encaissés, MRR estimé, paliers IA utilisés, compteur liste d'attente.
En mode JSON (sans base de données), les revenus restent à zéro sans erreur.
"""

import json
import pytest
from pathlib import Path
from fastapi.testclient import TestClient

ADMIN_LOGIN_URL = "/api/v1/admin/login"
STATS_URL = "/api/v1/admin/stats"


def _write_json(path: Path, data) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")


@pytest.fixture
def stats_env(tmp_path: Path, monkeypatch):
    import routes.waitlist_routes as waitlist_mod

    waitlist_file = tmp_path / "waitlist.json"
    monkeypatch.setattr(waitlist_mod, "WAITLIST_FILE", waitlist_file)
    return {"waitlist_file": waitlist_file}


@pytest.fixture
def client(stats_env, monkeypatch, tmp_path: Path):
    import services.auth_service as auth_svc
    from middleware.rate_limiting import RateLimitManager

    monkeypatch.setattr(auth_svc, "USERS_FILE", tmp_path / "users.json")
    monkeypatch.setattr(auth_svc, "USE_DATABASE", False)
    monkeypatch.setattr(auth_svc, "DATABASE_AVAILABLE", False)

    async def _check_request_allow(self, request):
        return True, "ok", "test"

    async def _check_translation_allow(self, request, file_size_mb=0):
        return True, "ok"

    monkeypatch.setattr(RateLimitManager, "check_request", _check_request_allow)
    monkeypatch.setattr(RateLimitManager, "check_translation", _check_translation_allow)

    from main import app

    return TestClient(app, raise_server_exceptions=True)


@pytest.fixture
def auth_headers(client, monkeypatch):
    import routes.admin_routes as admin_routes_mod

    monkeypatch.setattr(admin_routes_mod, "ADMIN_USERNAME", "admin")
    monkeypatch.setattr(admin_routes_mod, "ADMIN_PASSWORD", "admin-secret")
    monkeypatch.setattr(admin_routes_mod, "ADMIN_PASSWORD_HASH", None)
    r = client.post(ADMIN_LOGIN_URL, json={"password": "admin-secret"})
    assert r.status_code == 200, r.text
    return {"Authorization": f"Bearer {r.json()['access_token']}"}


def test_stats_include_revenue_mrr_waitlist_and_tiers(client, auth_headers, stats_env):
    _write_json(stats_env["waitlist_file"], [{"email": "a@example.com"}])

    r = client.get(STATS_URL, headers=auth_headers)
    assert r.status_code == 200, r.text
    body = r.json()

    # Nouveaux blocs présents
    for key in ("revenue", "mrr_estimated", "ai_tier_usage", "waitlist_count"):
        assert key in body, f"clé manquante dans /admin/stats : {key}"

    # Sans base de données : revenus à zéro, sans erreur
    assert body["revenue"]["collected_total"] == 0.0
    assert body["revenue"]["collected_30d"] == 0.0
    assert body["revenue"]["credits_purchased"] == 0.0

    # Compteur liste d'attente branché sur data/waitlist.json
    assert body["waitlist_count"] == 1

    # Paliers IA : structure complète
    assert set(body["ai_tier_usage"].keys()) == {
        "essential",
        "premium",
        "classic",
        "other",
    }

    # Anciennes clés toujours présentes (non-régression)
    assert "users" in body and "translations" in body and "cache" in body


def test_stats_mrr_estimated_from_plan_distribution(client, auth_headers, monkeypatch):
    """Le MRR estimé s'appuie sur la répartition des plans (prix mensuel effectif)."""
    import services.auth_service as auth_svc

    users_file = auth_svc.USERS_FILE
    users_file.parent.mkdir(parents=True, exist_ok=True)
    _write_json(
        users_file,
        {
            "u1": {
                "email": "p1@example.com",
                "name": "P1",
                "plan": "pro",
                "docs_translated_this_month": 0,
            },
            "u2": {
                "email": "p2@example.com",
                "name": "P2",
                "plan": "pro",
                "docs_translated_this_month": 0,
            },
        },
    )

    r = client.get(STATS_URL, headers=auth_headers)
    assert r.status_code == 200, r.text
    body = r.json()

    from services import pricing_config as pricing_cfg
    from models.subscription import PlanType

    monthly_pro, _ = pricing_cfg.get_effective_monthly_yearly(PlanType.PRO.value)
    assert body["users"]["by_plan"].get("pro") == 2
    assert body["mrr_estimated"]["by_plan"].get("pro") == pytest.approx(
        round(monthly_pro * 2, 2)
    )
    assert body["mrr_estimated"]["total"] == pytest.approx(
        round(monthly_pro * 2, 2)
    )


# ---------------------------------------------------------------------------
# Revenus et paliers IA en mode base de données (SQLite de test, cf. conftest)
# ---------------------------------------------------------------------------
@pytest.fixture
def db_client(monkeypatch, tmp_path: Path):
    """TestClient avec authentification admin simple et base de test active."""
    import services.auth_service as auth_svc
    from middleware.rate_limiting import RateLimitManager

    monkeypatch.setattr(auth_svc, "USERS_FILE", tmp_path / "users.json")
    monkeypatch.setattr(auth_svc, "USE_DATABASE", True)
    monkeypatch.setattr(auth_svc, "DATABASE_AVAILABLE", True)

    async def _check_request_allow(self, request):
        return True, "ok", "test"

    async def _check_translation_allow(self, request, file_size_mb=0):
        return True, "ok"

    monkeypatch.setattr(RateLimitManager, "check_request", _check_request_allow)
    monkeypatch.setattr(RateLimitManager, "check_translation", _check_translation_allow)

    import routes.admin_routes as admin_routes_mod

    monkeypatch.setattr(admin_routes_mod, "ADMIN_USERNAME", "admin")
    monkeypatch.setattr(admin_routes_mod, "ADMIN_PASSWORD", "admin-secret")
    monkeypatch.setattr(admin_routes_mod, "ADMIN_PASSWORD_HASH", None)

    from main import app

    return TestClient(app, raise_server_exceptions=True)


def test_stats_revenue_and_tiers_from_database(db_client):
    """Paiements réussis + traductions en base → revenus et paliers non nuls."""
    from database.connection import get_sync_session
    from database.models import User as DBUser, PaymentHistory, Translation

    with get_sync_session() as session:
        user = DBUser(
            email="payer@example.com",
            name="Payer",
            password_hash="not-a-real-hash",
        )
        session.add(user)
        session.flush()

        session.add_all(
            [
                PaymentHistory(
                    user_id=user.id,
                    amount_cents=1900,
                    currency="eur",
                    payment_type="subscription",
                    status="succeeded",
                ),
                PaymentHistory(
                    user_id=user.id,
                    amount_cents=900,
                    currency="eur",
                    payment_type="credits",
                    status="succeeded",
                ),
                PaymentHistory(
                    user_id=user.id,
                    amount_cents=5000,
                    currency="eur",
                    payment_type="subscription",
                    status="failed",  # jamais comptabilisé
                ),
                Translation(
                    user_id=user.id,
                    original_filename="a.xlsx",
                    file_type="xlsx",
                    target_language="fr",
                    provider="openrouter",
                    status="completed",
                ),
                Translation(
                    user_id=user.id,
                    original_filename="b.xlsx",
                    file_type="xlsx",
                    target_language="fr",
                    provider="openrouter_premium",
                    status="completed",
                ),
            ]
        )
        session.commit()

        r = db_client.get(STATS_URL, headers=_admin_headers(db_client))
        assert r.status_code == 200, r.text
        body = r.json()

        assert body["revenue"]["currency"] == "EUR"
        assert body["revenue"]["collected_total"] >= 28.0  # 19 € + 9 € (l'échec ignoré)
        assert body["revenue"]["collected_30d"] >= 28.0
        assert body["revenue"]["credits_purchased"] >= 9.0
        assert body["revenue"]["payments_30d"] >= 2
        assert body["ai_tier_usage"]["essential"] >= 1
        assert body["ai_tier_usage"]["premium"] >= 1


def _admin_headers(client) -> dict:
    r = client.post(ADMIN_LOGIN_URL, json={"password": "admin-secret"})
    assert r.status_code == 200, r.text
    return {"Authorization": f"Bearer {r.json()['access_token']}"}
