"""Teste US-003 (PRD 3.5): helper pur payload -> campuri afisabile.

Helper partajat web + API (DRY, eng review). Defensiv: nu arunca pe payload
malformat; tolerant la diferentele de chei intre canale (numar vs
numarInmatriculare) si la coercion Excel (odometru "123.0", VIN non-string).
"""

from __future__ import annotations

import json

from app.payload_view import prezentare_din_payload, EMPTY


def test_detalii_din_payload():
    """Payload complet -> toate campurile afisabile corecte."""
    payload = json.dumps({
        "vin": "WVWZZZ1JZXW000001",
        "nr_inmatriculare": "B123XYZ",
        "odometru_final": "123456",
        "data_prestatie": "2026-06-18",
        "prestatii": [{"cod_prestatie": "R-FRANE", "denumire": "Reparatie frane"}],
    })
    d = prezentare_din_payload(payload)
    assert d["vehicul_nr"] == "B123XYZ"
    assert d["vin"] == "WVWZZZ1JZXW000001"
    assert "000001" in d["vin_scurt"]  # trunchiat dar identificabil
    assert d["operatie"] == "Reparatie frane"
    assert d["cod"] == "R-FRANE"
    assert d["data_prestatie"] == "2026-06-18"
    assert d["odometru"] == "123456"


def test_payload_partial():
    """Campuri lipsa -> EMPTY, fara exceptie."""
    d = prezentare_din_payload(json.dumps({"vin": "WVWZZZ1JZXW000002"}))
    assert d["vin"] == "WVWZZZ1JZXW000002"
    assert d["vehicul_nr"] == EMPTY
    assert d["operatie"] == EMPTY
    assert d["cod"] == EMPTY
    assert d["data_prestatie"] == EMPTY
    assert d["odometru"] == EMPTY


def test_payload_gol():
    """Payload gol / None -> toate EMPTY, fara exceptie."""
    for p in (None, "", "{}", {}):
        d = prezentare_din_payload(p)
        assert d["vehicul_nr"] == EMPTY
        assert d["vin"] == EMPTY


def test_payload_invalid():
    """JSON invalid / tip neasteptat -> fallback grijuliu (nu arunca)."""
    for bad in ("nu-e-json", "[1,2,3]", "null", "12345"):
        d = prezentare_din_payload(bad)
        assert d["vin"] == EMPTY  # degradeaza curat


def test_payload_coercion_excel():
    """Odometru '123.0'/numeric si VIN non-string afisate curat; chei API alternative."""
    # Excel coercion: odometru float-string si numeric
    d1 = prezentare_din_payload({"odometru_final": "123456.0"})
    assert d1["odometru"] == "123456"
    d2 = prezentare_din_payload({"odometru_final": 123456})
    assert d2["odometru"] == "123456"
    # VIN non-string (coercion Excel)
    d3 = prezentare_din_payload({"vin": 12345678901234567})
    assert d3["vin"] == "12345678901234567"
    # Chei alternative canal API (numar / numarInmatriculare / odometru)
    d4 = prezentare_din_payload({"numar": "CJ99ABC", "odometru": "777.0"})
    assert d4["vehicul_nr"] == "CJ99ABC"
    assert d4["odometru"] == "777"
    d5 = prezentare_din_payload({"numarInmatriculare": "TM01AAA"})
    assert d5["vehicul_nr"] == "TM01AAA"


def test_operatie_fallback_la_cod():
    """Fara denumire -> operatie afiseaza codul; cod intern cand lipseste cel RAR."""
    d = prezentare_din_payload({"prestatii": [{"cod_op_service": "OP-77"}]})
    assert d["cod"] == "OP-77"
    assert d["operatie"] == "OP-77"


# --- US-005: cod_rar distinct ---

def test_cod_rar_prezent_cand_mapat():
    """cod_prestatie prezent -> cod_rar e uppercase + strip '.0'."""
    d = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "r-frane", "denumire": "Reparatie frane"}]
    })
    assert d["cod_rar"] == "R-FRANE"

    # defensiv ca odometru: strip '.0' chiar daca codurile RAR nu au zecimale
    d2 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "oe-2.0"}]
    })
    assert d2["cod_rar"] == "OE-2"

    # deja uppercase + fara zecimale -> trece neschimbat
    d3 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "OE-2", "denumire": "Verificare"}]
    })
    assert d3["cod_rar"] == "OE-2"


def test_cod_rar_gol_cand_nemapat():
    """cod_prestatie absent/None -> cod_rar == EMPTY; NU cade pe cod_op_service."""
    # doar cod_op_service prezent
    d = prezentare_din_payload({
        "prestatii": [{"cod_op_service": "OP-77", "denumire": "Verificare faruri"}]
    })
    assert d["cod_rar"] == EMPTY

    # fara prestatii deloc
    d2 = prezentare_din_payload({"vin": "WVWZZZ1JZXW000001"})
    assert d2["cod_rar"] == EMPTY

    # cod_prestatie explicit None
    d3 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": None, "cod_op_service": "OP-99"}]
    })
    assert d3["cod_rar"] == EMPTY


def test_operatie_ramane_denumire_sau_op():
    """operatie si cod raman neschimbate (compatibilitate cu apelantii existenti)."""
    # cu ambele coduri -> operatie=denumire, cod=cod_prestatie (neschimbat)
    d = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "R-FRANE", "cod_op_service": "OP-1",
                       "denumire": "Reparatie frane"}]
    })
    assert d["operatie"] == "Reparatie frane"
    assert d["cod"] == "R-FRANE"

    # fara denumire, doar cod_op_service -> operatie=cod intern, cod=cod intern
    d2 = prezentare_din_payload({
        "prestatii": [{"cod_op_service": "OP-77"}]
    })
    assert d2["operatie"] == "OP-77"
    assert d2["cod"] == "OP-77"

    # cod_rar nu afecteaza cod si operatie
    d3 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "oe-2", "denumire": "Verificare"}]
    })
    assert d3["operatie"] == "Verificare"
    assert d3["cod"] == "oe-2"  # cod ramas neschimbat (nu uppercase)


# --- US-002: op_service_cod + op_service_denumire distincte ---

def test_operatie_service_din_cod_op_service():
    """cod_op_service prezent -> op_service_cod contine valoarea; string gol cand lipseste."""
    # cod_op_service prezent -> op_service_cod populated
    d = prezentare_din_payload({
        "prestatii": [{"cod_op_service": "OP-77", "denumire": "Verificare faruri"}]
    })
    assert d["op_service_cod"] == "OP-77"

    # cod_op_service absent (vine direct cu cod_prestatie) -> op_service_cod == "" (NU EMPTY="—")
    d2 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "R-FRANE", "denumire": "Reparatie frane"}]
    })
    assert d2["op_service_cod"] == ""
    assert d2["op_service_cod"] != "—"


def test_operatie_service_din_denumire():
    """denumire prezenta cu cod_op_service -> op_service_denumire contine valoarea."""
    # ambele prezente -> op_service_denumire = denumire
    d = prezentare_din_payload({
        "prestatii": [{"cod_op_service": "OP-77", "denumire": "Verificare faruri"}]
    })
    assert d["op_service_denumire"] == "Verificare faruri"

    # cod_op_service prezent dar fara denumire -> op_service_denumire == ""
    d2 = prezentare_din_payload({
        "prestatii": [{"cod_op_service": "OP-77"}]
    })
    assert d2["op_service_denumire"] == ""

    # cod_op_service absent + denumire prezenta -> op_service_denumire == "" (nu expune denumire RAR)
    d3 = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "R-FRANE", "denumire": "Reparatie frane"}]
    })
    assert d3["op_service_denumire"] == ""


def test_fara_operatie_service_cand_lipseste():
    """Payload fara cod_op_service -> op_service_cod si op_service_denumire sunt "" (nu "—"), fara exceptie."""
    # vine direct cu cod_prestatie
    d = prezentare_din_payload({
        "prestatii": [{"cod_prestatie": "R-FRANE"}]
    })
    assert d["op_service_cod"] == ""
    assert d["op_service_denumire"] == ""
    assert d["op_service_cod"] != "—"
    assert d["op_service_denumire"] != "—"

    # fara prestatii deloc
    d2 = prezentare_din_payload({"vin": "WVWZZZ1JZXW000001"})
    assert d2["op_service_cod"] == ""
    assert d2["op_service_denumire"] == ""

    # payload None/gol
    d3 = prezentare_din_payload(None)
    assert d3["op_service_cod"] == ""
    assert d3["op_service_denumire"] == ""

    # payload JSON invalid
    d4 = prezentare_din_payload("nu-e-json")
    assert d4["op_service_cod"] == ""
    assert d4["op_service_denumire"] == ""
