"""Teste US-005 — camp rar_env pe POST /v1/prezentari si /valideaza.

Acopera: default din cont, tinta explicita, respingere tinta indisponibila,
echo GET, valoare invalida (422 Pydantic), echo dry-run valideaza.
"""

from __future__ import annotations

import os
import tempfile

import pytest
from fastapi.testclient import TestClient


@pytest.fixture()
def env(monkeypatch):
    """DB temporara izolata per test + settings reincarcate."""
    tmp = tempfile.mkdtemp()
    monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "t.db"))
    from app.config import get_settings
    get_settings.cache_clear()
    yield monkeypatch
    get_settings.cache_clear()


def _client():
    from app.main import app
    return TestClient(app)


def _body(rar_env=None, **over):
    prez = {
        "vin": "WVWZZZ1KZAW000123",
        "nr_inmatriculare": "B999TST",
        "data_prestatie": "2026-06-15",
        "odometru_final": "123456",
        "prestatii": [{"cod_prestatie": "OE-1"}],
    }
    prez.update(over)
    body = {"rar_credentials": {"email": "x@y.ro", "password": "s"}, "prezentari": [prez]}
    if rar_env is not None:
        body["rar_env"] = rar_env
    return body


def _setup_prod_only(conn):
    """Configureaza contul 1 ca prod-only (rar_prod_enabled=1, creds prod, default prod)."""
    from app.crypto import encrypt_creds
    enc = encrypt_creds({"email": "prod@rar.ro", "password": "paraprod"})
    conn.execute(
        "UPDATE accounts SET rar_prod_enabled=1, rar_creds_prod_enc=?, "
        "rar_test_enabled=0, rar_creds_test_enc=NULL, rar_env_default='prod' WHERE id=1",
        (enc,),
    )
    conn.commit()


def _setup_dual_env(conn):
    """Configureaza contul 1 cu ambele medii disponibile, default test."""
    from app.crypto import encrypt_creds
    enc_test = encrypt_creds({"email": "test@rar.ro", "password": "paratest"})
    enc_prod = encrypt_creds({"email": "prod@rar.ro", "password": "paraprod"})
    conn.execute(
        "UPDATE accounts SET rar_prod_enabled=1, rar_creds_prod_enc=?, "
        "rar_test_enabled=1, rar_creds_test_enc=?, rar_env_default='test' WHERE id=1",
        (enc_prod, enc_test),
    )
    conn.commit()


# --------------------------------------------------------------------------- #
# test_default_din_cont_cand_lipseste                                          #
# --------------------------------------------------------------------------- #

def test_default_din_cont_cand_lipseste(env):
    """Cont prod-only, POST fara rar_env -> submission rar_env='prod'."""
    with _client() as c:
        from app.db import get_connection
        conn = get_connection()
        try:
            _setup_prod_only(conn)
        finally:
            conn.close()

        r = c.post("/v1/prezentari", json=_body())
        assert r.status_code == 200, r.text
        res = r.json()["results"][0]
        assert res["status"] == "queued"
        assert res["rar_env"] == "prod"


# --------------------------------------------------------------------------- #
# test_target_explicit                                                          #
# --------------------------------------------------------------------------- #

def test_target_explicit(env):
    """Cont cu ambele medii, POST cu rar_env='test' -> submission rar_env='test'."""
    with _client() as c:
        from app.db import get_connection
        conn = get_connection()
        try:
            _setup_dual_env(conn)
        finally:
            conn.close()

        r = c.post("/v1/prezentari", json=_body(rar_env="test"))
        assert r.status_code == 200, r.text
        res = r.json()["results"][0]
        assert res["status"] == "queued"
        assert res["rar_env"] == "test"

        # Aceeasi prezentare cu rar_env='prod' -> cheie diferita (env-aware) -> alt submission
        r2 = c.post("/v1/prezentari", json=_body(rar_env="prod"))
        assert r2.status_code == 200, r2.text
        res2 = r2.json()["results"][0]
        assert res2["rar_env"] == "prod"
        # Nu e dedup (env diferit -> cheie diferita)
        assert res2["submission_id"] != res["submission_id"]


# --------------------------------------------------------------------------- #
# test_target_indisponibil_respins                                              #
# --------------------------------------------------------------------------- #

def test_target_indisponibil_respins(env):
    """Cont prod-only, POST cu rar_env='test' -> 422 RAR_MEDIU_INDISPONIBIL, fara enqueue."""
    with _client() as c:
        from app.db import get_connection
        conn = get_connection()
        try:
            _setup_prod_only(conn)
        finally:
            conn.close()

        r = c.post("/v1/prezentari", json=_body(rar_env="test"))
        assert r.status_code == 422, r.text
        detail = r.json()["detail"]
        assert detail["cod"] == "RAR_MEDIU_INDISPONIBIL"
        # Cauza contine mediul cerut si lista disponibilelor
        assert "test" in detail["cauza"]
        assert "prod" in detail["cauza"]

        # Verifica ca nu s-a facut enqueue
        lista = c.get("/v1/prezentari").json()["submissions"]
        assert lista == []


# --------------------------------------------------------------------------- #
# test_get_ecou_rar_env                                                        #
# --------------------------------------------------------------------------- #

def test_get_ecou_rar_env(env):
    """Dupa enqueue, GET /v1/prezentari/{id} si lista contin rar_env."""
    with _client() as c:
        from app.db import get_connection
        conn = get_connection()
        try:
            _setup_prod_only(conn)
        finally:
            conn.close()

        # Enqueue pe prod (default contului prod-only)
        r = c.post("/v1/prezentari", json=_body())
        assert r.status_code == 200, r.text
        sub_id = r.json()["results"][0]["submission_id"]
        assert sub_id is not None

        # GET detaliu
        r_det = c.get(f"/v1/prezentari/{sub_id}")
        assert r_det.status_code == 200, r_det.text
        assert r_det.json()["rar_env"] == "prod"

        # GET lista
        r_lst = c.get("/v1/prezentari")
        assert r_lst.status_code == 200, r_lst.text
        sub_in_lista = next(s for s in r_lst.json()["submissions"] if s["id"] == sub_id)
        assert sub_in_lista["rar_env"] == "prod"


# --------------------------------------------------------------------------- #
# test_valoare_invalida_422                                                     #
# --------------------------------------------------------------------------- #

def test_valoare_invalida_422(env):
    """POST cu rar_env='staging' -> 422 din Pydantic Literal, fara echo de input."""
    with _client() as c:
        body = _body(rar_env="staging")
        r = c.post("/v1/prezentari", json=body)
        assert r.status_code == 422, r.text
        # Handler-ul global sterge 'input'/'ctx' — valoarea invalida nu se ecou-ieste.
        assert "staging" not in r.text
        # Fara enqueue
        lista = c.get("/v1/prezentari").json()["submissions"]
        assert lista == []


# --------------------------------------------------------------------------- #
# test_valideaza_ecou_rar_env                                                  #
# --------------------------------------------------------------------------- #

def test_valideaza_ecou_rar_env(env):
    """POST /valideaza (dry-run) ecou-ieste rar_env rezolvat in ValidareResult."""
    with _client() as c:
        from app.db import get_connection
        conn = get_connection()
        try:
            _setup_prod_only(conn)
        finally:
            conn.close()

        # Dry-run fara rar_env -> default cont = prod
        r = c.post("/v1/prezentari/valideaza", json=_body())
        assert r.status_code == 200, r.text
        res = r.json()["results"][0]
        assert res["rar_env"] == "prod"

        # Dry-run cu rar_env='prod' explicit
        r2 = c.post("/v1/prezentari/valideaza", json=_body(rar_env="prod"))
        assert r2.status_code == 200, r2.text
        assert r2.json()["results"][0]["rar_env"] == "prod"

        # Dry-run tinta indisponibila -> 422, fara echo sensibil
        r3 = c.post("/v1/prezentari/valideaza", json=_body(rar_env="test"))
        assert r3.status_code == 422, r3.text
        assert r3.json()["detail"]["cod"] == "RAR_MEDIU_INDISPONIBIL"
