"""US-001: stare chips extinsa (JSON versionat, D4) + actiuni add/remove unificate.

Contract nou /form-chips:
- Stare curenta: UN SINGUR hidden `chips_state` = JSON {"v":1,"items":[{"cod","op","den","exclus"}]}.
- chips_action=add + chips_pick (codul ales) + chips_target_index optional:
  cu tinta -> leaga codul de operatia de la acel index; fara tinta -> chip liber.
  chips_pick=__NEDECLARAT__ + tinta valida -> item exclus=1, fara cod_prestatie.
- chips_action=remove + chips_remove_index: chip legat de operatie -> revine warning
  (cod_prestatie="", exclus=0); chip liber -> iese din lista.
- Actiunile vechi (add_flat/add_extra/remove_flat/chips_add_cod_{i}/chips_add_cod_flat
  ca actiuni) sunt ELIMINATE.
"""

from __future__ import annotations

import json
import os
import re
import tempfile

import pytest
from starlette.testclient import TestClient


# --------------------------------------------------------------------------- #
# Fixtures                                                                     #
# --------------------------------------------------------------------------- #

@pytest.fixture()
def client(monkeypatch):
    tmp = tempfile.mkdtemp()
    monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "chips.db"))
    monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "true")
    from app.config import get_settings
    get_settings.cache_clear()
    from app.web import ratelimit
    ratelimit._hits.clear()
    from app.main import app
    with TestClient(app, follow_redirects=False) as c:
        yield c
    ratelimit._hits.clear()
    get_settings.cache_clear()


def _create_account_user(email: str, password: str = "parolasecreta10"):
    from app.accounts import create_account
    from app.users import create_user
    from app.db import get_connection
    conn = get_connection()
    try:
        acct_id = create_account(conn, "Service", active=True)
        create_user(conn, acct_id, email, password)
        return acct_id
    finally:
        conn.close()


def _login(client, email: str, password: str = "parolasecreta10") -> None:
    resp = client.get("/login")
    m = re.search(r'name="csrf_token"\s+value="([^"]+)"', resp.text) or \
        re.search(r'value="([^"]+)"\s+name="csrf_token"', resp.text)
    assert m, "csrf_token nu gasit in login"
    resp = client.post("/login", data={"email": email, "parola": password, "csrf_token": m.group(1)})
    assert resp.status_code == 303


def _csrf(client) -> str:
    resp = client.get("/?tab=coada")
    m = re.search(r'name="csrf_token"\s+value="([^"]+)"', resp.text)
    assert m, "csrf_token nu gasit in dashboard"
    return m.group(1)


def _seed_cod(cod: str, denumire: str = "Prestatie test") -> None:
    from app.db import get_connection
    conn = get_connection()
    try:
        conn.execute(
            "INSERT OR REPLACE INTO nomenclator_rar (cod_prestatie, nume_prestatie) VALUES (?, ?)",
            (cod, denumire),
        )
        conn.commit()
    finally:
        conn.close()


def _state(items: list[dict]) -> str:
    """Construieste JSON-ul hidden chips_state din itemi scurti {cod,op,den,exclus}."""
    return json.dumps({"v": 1, "items": items}, ensure_ascii=False)


def _login_seed(client, email: str) -> None:
    _create_account_user(email)
    _login(client, email)


# --------------------------------------------------------------------------- #
# add cu tinta -> leaga codul de operatia respectiva                          #
# --------------------------------------------------------------------------- #

def test_add_cu_tinta_leaga_de_operatie(client):
    _login_seed(client, "add.tinta@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    state = _state([
        {"cod": "", "op": "Op-A", "den": "Schimb ulei motor", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "add",
        "chips_target_index": "0",
        "chips_pick": "OE-1",
    })
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text
    assert "OE-1" in html

    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', html)
    assert m, f"hidden chips_state lipsa din raspuns: {html[:400]}"
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["v"] == 1
    items = payload["items"]
    assert len(items) == 1
    assert items[0]["cod"] == "OE-1"
    assert items[0]["op"] == "Op-A"
    assert items[0]["exclus"] == 0


# --------------------------------------------------------------------------- #
# add fara tinta -> chip liber                                                #
# --------------------------------------------------------------------------- #

def test_add_fara_tinta_adauga_cod_liber(client):
    _login_seed(client, "add.liber@test.com")
    _seed_cod("FRN1", "Sistem de franare")
    csrf = _csrf(client)

    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": _state([]),
        "chips_action": "add",
        "chips_pick": "FRN1",
    })
    assert resp.status_code == 200, resp.text[:400]
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    items = payload["items"]
    assert len(items) == 1
    assert items[0]["cod"] == "FRN1"
    assert items[0]["op"] == ""


# --------------------------------------------------------------------------- #
# add __NEDECLARAT__ cu tinta -> marcheaza exclus                             #
# --------------------------------------------------------------------------- #

def test_add_nedeclarat_marcheaza_exclus(client):
    _login_seed(client, "add.ned@test.com")
    csrf = _csrf(client)

    state = _state([
        {"cod": "", "op": "OP-ITP", "den": "Inspectie tehnica", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "add",
        "chips_target_index": "0",
        "chips_pick": "__NEDECLARAT__",
    })
    assert resp.status_code == 200, resp.text[:400]
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    items = payload["items"]
    assert len(items) == 1
    assert items[0]["exclus"] == 1
    assert items[0]["cod"] == "", f"item exclus nu trebuie sa aiba cod_prestatie: {items[0]}"
    assert items[0]["op"] == "OP-ITP"
    assert "nu se va declara" in resp.text.lower()


def test_add_nedeclarat_fara_tinta_da_eroare(client):
    """Sentinelul __NEDECLARAT__ fara tinta valida -> chips_error explicit, fara modificare."""
    _login_seed(client, "add.ned.notinta@test.com")
    csrf = _csrf(client)

    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": _state([]),
        "chips_action": "add",
        "chips_pick": "__NEDECLARAT__",
        # fara chips_target_index
    })
    assert resp.status_code == 200, resp.text[:400]
    assert "chips-extra-error" in resp.text, (
        f"Eroare vizibila lipsa pentru NEDECLARAT fara tinta: {resp.text[:400]}"
    )
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["items"] == [], "NEDECLARAT fara tinta nu trebuie sa modifice starea"


def test_add_nedeclarat_tinta_deja_mapata_da_eroare(client):
    """Tinta trebuie sa fie o operatie NEMAPATA — index spre operatie deja rezolvata -> eroare."""
    _login_seed(client, "add.ned.mapata@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    state = _state([
        {"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "add",
        "chips_target_index": "0",
        "chips_pick": "__NEDECLARAT__",
    })
    assert resp.status_code == 200
    assert "chips-extra-error" in resp.text
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["items"][0]["cod"] == "OE-1", "Tinta invalida nu trebuie sa strice starea existenta"


# --------------------------------------------------------------------------- #
# remove -> readuce operatia nemapata (warning)                               #
# --------------------------------------------------------------------------- #

def test_remove_cod_readuce_operatia_nemapata(client):
    _login_seed(client, "remove.readuce@test.com")
    csrf = _csrf(client)

    state = _state([
        {"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "remove",
        "chips_remove_index": "0",
    })
    assert resp.status_code == 200, resp.text[:400]
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    items = payload["items"]
    assert len(items) == 1, "Operatia trebuie sa RAMANA (doar codul dispare)"
    assert items[0]["cod"] == ""
    assert items[0]["op"] == "Op-A"
    assert items[0]["exclus"] == 0


def test_remove_pe_nedeclarat_readuce_warning(client):
    """x pe un chip Nedeclarat readuce operatia la warning (nu se sterge operatia)."""
    _login_seed(client, "remove.nedeclarat@test.com")
    csrf = _csrf(client)

    state = _state([
        {"cod": "", "op": "OP-ITP", "den": "Inspectie", "exclus": 1},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "remove",
        "chips_remove_index": "0",
    })
    assert resp.status_code == 200
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    items = payload["items"]
    assert len(items) == 1
    assert items[0]["exclus"] == 0
    assert items[0]["cod"] == ""
    assert items[0]["op"] == "OP-ITP"


def test_remove_cod_liber_il_sterge_complet(client):
    """Chip liber (fara operatie sursa) e eliminat integral din lista la remove."""
    _login_seed(client, "remove.liber@test.com")
    csrf = _csrf(client)

    state = _state([
        {"cod": "FRN1", "op": "", "den": "", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "remove",
        "chips_remove_index": "0",
    })
    assert resp.status_code == 200
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["items"] == []


# --------------------------------------------------------------------------- #
# dedup (operatie, cod)                                                       #
# --------------------------------------------------------------------------- #

def test_dedup_operatie_cod(client):
    """Acelasi cod liber nu se adauga de doua ori (pereche op='',cod deja existenta)."""
    _login_seed(client, "dedup.op.cod@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    state = _state([
        {"cod": "OE-1", "op": "", "den": "", "exclus": 0},
    ])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": "add",
        "chips_pick": "OE-1",
    })
    assert resp.status_code == 200
    assert "chips-extra-error" in resp.text or "deja in lista" in resp.text
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert len(payload["items"]) == 1, f"Dedup a esuat, itemi: {payload['items']}"


# --------------------------------------------------------------------------- #
# actiuni vechi eliminate                                                     #
# --------------------------------------------------------------------------- #

@pytest.mark.parametrize("actiune", ["add_flat", "add_extra", "remove_flat"])
def test_actiuni_vechi_eliminate_sunt_no_op(client, actiune):
    """Actiunile eliminate nu mai au ramura dedicata — cad prin fara sa schimbe starea."""
    _login_seed(client, f"vechi.{actiune}@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    state = _state([{"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0}])
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": state,
        "chips_action": actiune,
        "chips_add_cod_flat": "FRN1",
        "chips_remove_cod": "OE-1",
    })
    assert resp.status_code == 200
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["items"] == [{"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0}]


# --------------------------------------------------------------------------- #
# chips_state prezent mereu, inclusiv gol                                     #
# --------------------------------------------------------------------------- #

def test_chips_state_gol_ramane_prezent_in_raspuns(client):
    _login_seed(client, "state.gol@test.com")
    csrf = _csrf(client)
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": _state([]),
        "chips_action": "",
    })
    assert resp.status_code == 200
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m, "hidden chips_state trebuie sa fie mereu prezent, chiar cu lista goala"
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload == {"v": 1, "items": []}


# --------------------------------------------------------------------------- #
# JSON invalid -> eroare vizibila, nu stare goala silentioasa                 #
# --------------------------------------------------------------------------- #

def test_chips_state_json_invalid_da_eroare_vizibila(client):
    _login_seed(client, "state.corupt@test.com")
    csrf = _csrf(client)
    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        "chips_state": "{not valid json",
        "chips_action": "",
    })
    assert resp.status_code == 200
    assert "chips-extra-error" in resp.text or "invalid" in resp.text.lower(), (
        f"JSON corupt trebuie sa dea eroare vizibila: {resp.text[:400]}"
    )


# --------------------------------------------------------------------------- #
# compat tranzitorie: chips_state lipsa -> fallback pe listele vechi          #
# --------------------------------------------------------------------------- #

def test_compat_fallback_pe_liste_vechi_cand_chips_state_lipseste(client):
    _login_seed(client, "compat.fallback@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    resp = client.post("/form-chips", data={
        "csrf_token": csrf,
        # FARA chips_state -> fallback pe listele vechi
        "cod_prestatie": [""],
        "chip_op_service": ["Op-A"],
        "chip_denumire": ["Schimb ulei motor"],
        "chips_action": "add",
        "chips_target_index": "0",
        "chips_pick": "OE-1",
    })
    assert resp.status_code == 200, resp.text[:400]
    m = re.search(r'name="chips_state"\s+value=\'([^\']*)\'', resp.text)
    assert m
    payload = json.loads(m.group(1).replace("&#34;", '"'))
    assert payload["items"][0]["cod"] == "OE-1"
    assert payload["items"][0]["exclus"] == 0


# =========================================================================== #
# US-002: template unificat -- un container .chips, un select, fara op-row   #
# =========================================================================== #


def _post_chips(client, csrf, items, **extra):
    data = {
        "csrf_token": csrf,
        "chips_state": _state(items),
        "chips_action": "",
    }
    data.update(extra)
    return client.post("/form-chips", data=data)


def test_render_un_singur_container_chips(client):
    """UN singur container `.chips` -- indiferent de mixul de tipuri de chip."""
    _login_seed(client, "un.container@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    items = [
        {"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0},
        {"cod": "", "op": "Op-B", "den": "Vulcanizare", "exclus": 0},
        {"cod": "FRN1", "op": "", "den": "", "exclus": 0},
        {"cod": "", "op": "Op-C", "den": "ITP anual", "exclus": 1},
    ]
    _seed_cod("FRN1", "Sistem de franare")
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert html.count('class="chips"') == 1, (
        f"Trebuie sa existe UN SINGUR container .chips, gasit {html.count('class=\"chips\"')}: {html[:800]}"
    )


def test_render_fara_op_row_si_fara_butoane_adauga(client):
    """Fara .op-row, fara butoane Adauga/+, fara actiunile vechi in markup."""
    _login_seed(client, "fara.oprow@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    items = [
        {"cod": "OE-1", "op": "Op-A", "den": "Schimb ulei", "exclus": 0},
        {"cod": "", "op": "Op-B", "den": "Vulcanizare", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert "op-row" not in html
    assert "Adauga" not in html
    assert "add_flat" not in html
    assert "chips_add_cod_" not in html


def test_chip_warning_pentru_operatie_nemapata(client):
    """Operatie nemapata -> chip warning `warn OP-X . fara cod` cu title complet."""
    _login_seed(client, "chip.warning@test.com")
    csrf = _csrf(client)

    items = [
        {"cod": "", "op": "OP-ITP", "den": "Inspectie tehnica periodica", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert "OP-ITP" in html
    assert "fara cod" in html
    assert 'title="OP-ITP' in html


def test_select_are_hx_disabled_elt_this(client):
    """Selectul unic are hx-disabled-elt='this' EXPLICIT (capcana 5.22 -- nu mostenit de la form)."""
    _login_seed(client, "select.disabled@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    resp = _post_chips(client, csrf, [])
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    m = re.search(r'<select[^>]*name="chips_pick"[^>]*>', html)
    assert m, f"selectul chips_pick lipseste: {html[:600]}"
    select_tag = m.group(0)
    assert 'id="chips-picker"' in select_tag
    assert 'hx-trigger="change"' in select_tag
    assert 'hx-post="/form-chips"' in select_tag
    assert 'hx-target="#chips-section"' in select_tag
    assert 'hx-swap="outerHTML"' in select_tag
    assert 'hx-include="closest form"' in select_tag
    assert 'hx-disabled-elt="this"' in select_tag, (
        f"hx-disabled-elt='this' lipseste de pe select (capcana 5.22): {select_tag}"
    )


def test_mod_plat_fara_operatii_select_doar_coduri_libere(client):
    """Mod plat (zero operatii din import): doar chips libere + select placeholder generic."""
    _login_seed(client, "mod.plat@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    items = [
        {"cod": "OE-1", "op": "", "den": "", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert "⚠" not in html, "Mod plat nu trebuie sa aiba niciun chip warning"
    m = re.search(r'<select[^>]*name="chips_pick"[^>]*>\s*<option value="">([^<]*)</option>', html)
    assert m, f"select cu optiune placeholder lipseste: {html[:600]}"
    assert "adauga cod RAR" in m.group(1)


def test_has_r_odo_pastrat_dupa_actiuni(client):
    """has_r_odo / data-has-r-odo + chip-warn pe R-ODO/I-ODO raman neschimbate."""
    _login_seed(client, "r.odo@test.com")
    _seed_cod("R-ODO", "Odometru initial")
    csrf = _csrf(client)

    items = [
        {"cod": "R-ODO", "op": "", "den": "", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert 'data-has-r-odo="true"' in html
    assert "chip-warn" in html
    assert "R-ODO" in html


def test_chip_nedeclarat_are_x_functional(client):
    """Item exclus=1 -> chip Nedeclarat (line-through) cu buton de sters functional (remove -> warning)."""
    _login_seed(client, "nedeclarat.x@test.com")
    csrf = _csrf(client)

    items = [
        {"cod": "", "op": "OP-ITP", "den": "Inspectie", "exclus": 1},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert "Nedeclarat" in html
    assert 'hx-vals=\'{"chips_action":"remove","chips_remove_index":0}\'' in html


def test_chips_submission_id_ecouat(client):
    """chips_submission_id trimis in form e ecouat ca hidden in raspunsul /form-chips."""
    _login_seed(client, "sub.id.ecou@test.com")
    csrf = _csrf(client)

    resp = _post_chips(client, csrf, [], chips_submission_id="4242")
    assert resp.status_code == 200, resp.text[:400]
    assert re.search(r'name="chips_submission_id"\s+value="4242"', resp.text), (
        f"chips_submission_id nu a fost ecouat: {resp.text[:600]}"
    )


# =========================================================================== #
# US-003: sugestii fuzzy/k-NN + optiunea "Nu se declara la RAR" in select    #
# =========================================================================== #


def _extrage_select(html: str) -> str:
    """Extrage markup-ul complet al <select name="chips_pick">...</select>."""
    m = re.search(r'<select[^>]*name="chips_pick".*?</select>', html, re.DOTALL)
    assert m, f"select chips_pick lipseste din raspuns: {html[:600]}"
    return m.group(0)


def test_select_are_optgroup_sugestii_pt_tinta(client):
    """Cu tinta activa (operatie nemapata): optgroup 'Sugestii' + __NEDECLARAT__ + nomenclator."""
    _login_seed(client, "sugestii.tinta@test.com")
    _seed_cod("OE-1", "Schimb ulei motor")
    _seed_cod("FRN1", "Sistem de franare")
    csrf = _csrf(client)

    items = [
        {"cod": "", "op": "Op-A", "den": "Schimb ulei motor", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    select_html = _extrage_select(resp.text)

    assert '<optgroup label="Sugestii">' in select_html, (
        f"optgroup Sugestii lipseste cu tinta activa: {select_html[:600]}"
    )
    assert "OE-1" in select_html.split('<optgroup label="Sugestii">')[1].split("</optgroup>")[0], (
        "sugestia fuzzy pentru 'Schimb ulei motor' trebuie sa contina OE-1"
    )
    assert "__NEDECLARAT__" in select_html
    assert "Nu se declara la RAR" in select_html
    # Nomenclatorul complet ramane dupa Sugestii/NEDECLARAT.
    assert "FRN1" in select_html


def test_select_are_nedeclarat_doar_cu_tinta(client):
    """Optiunea __NEDECLARAT__ apare DOAR cand exista o tinta (operatie nemapata) activa."""
    _login_seed(client, "nedeclarat.doar.tinta@test.com")
    _seed_cod("OE-1", "Schimb ulei")
    csrf = _csrf(client)

    # Cu tinta (operatie nemapata) -> NEDECLARAT prezent.
    resp_cu_tinta = _post_chips(client, csrf, [
        {"cod": "", "op": "Op-A", "den": "Schimb ulei", "exclus": 0},
    ])
    assert "__NEDECLARAT__" in _extrage_select(resp_cu_tinta.text)

    # Fara tinta (doar cod liber, nicio operatie nemapata) -> NEDECLARAT absent.
    resp_fara_tinta = _post_chips(client, csrf, [
        {"cod": "OE-1", "op": "", "den": "", "exclus": 0},
    ])
    assert "__NEDECLARAT__" not in _extrage_select(resp_fara_tinta.text)


def test_select_fara_tinta_fara_sugestii(client):
    """Fara tinta: selectul listeaza DOAR nomenclatorul (fara optgroup Sugestii, fara NEDECLARAT)."""
    _login_seed(client, "fara.tinta.fara.sugestii@test.com")
    _seed_cod("OE-1", "Schimb ulei motor")
    csrf = _csrf(client)

    items = [
        {"cod": "OE-1", "op": "", "den": "", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    select_html = _extrage_select(resp.text)

    assert "<optgroup" not in select_html
    assert "__NEDECLARAT__" not in select_html
    assert "OE-1" in select_html


def test_sugestii_indisponibile_degradare_fara_optgroup(client, monkeypatch):
    """Motor de sugestii care arunca exceptie -> select DOAR cu nomenclatorul (fara optgroup),
    fara eroare 500 si fara blocare (degradare gratioasa, GAP inchis din PRD 5.23)."""
    _login_seed(client, "sugestii.indisponibile@test.com")
    _seed_cod("OE-1", "Schimb ulei motor")
    csrf = _csrf(client)

    from app.web import routes as _routes

    def _boom(*args, **kwargs):
        raise RuntimeError("motor de sugestii indisponibil (simulat)")

    monkeypatch.setattr(_routes, "suggest_codes", _boom)
    monkeypatch.setattr(_routes, "enrich_suggestions", _boom)

    items = [
        {"cod": "", "op": "Op-A", "den": "Schimb ulei motor", "exclus": 0},
    ]
    resp = _post_chips(client, csrf, items)
    assert resp.status_code == 200, resp.text[:400]
    select_html = _extrage_select(resp.text)

    assert "<optgroup" not in select_html, (
        f"optgroup nu trebuie sa apara cand motorul de sugestii arunca exceptie: {select_html[:600]}"
    )
    assert "OE-1" in select_html, "nomenclatorul complet trebuie sa ramana disponibil"


# =========================================================================== #
# FIX: tinta implicita + sugestii la RANDAREA INITIALA a modalului (fara       #
# niciun round-trip /form-chips) — invariant PRD 5.23 §3.1.                  #
# =========================================================================== #

def _insert_submission(acct: int, *, status: str, payload: dict) -> int:
    from app.db import get_connection
    conn = get_connection()
    try:
        cur = conn.execute(
            "INSERT INTO submissions (idempotency_key, account_id, status, payload_json) "
            "VALUES (?, ?, ?, ?)",
            (f"k-{os.urandom(6).hex()}", acct, status, json.dumps(payload)),
        )
        conn.commit()
        return int(cur.lastrowid)
    finally:
        conn.close()


def test_randare_initiala_are_tinta_si_optgroup(client):
    """Deschiderea INITIALA a modalului de detaliu (needs_mapping, operatie nemapata),
    FARA niciun /form-chips, trebuie sa aiba deja is-target pe chip-ul warning,
    placeholder-ul D2 "Cod pentru OP-X — alege" si optgroup-ul Sugestii + NEDECLARAT."""
    acct = _login_seed_ret(client, "randare.initiala@test.com")
    _seed_cod("OE-1", "Schimb ulei motor")
    _seed_cod("FRN1", "Sistem de franare")

    op = "Schimb ulei motor"
    sid = _insert_submission(acct, status="needs_mapping", payload={
        "vin": "WVWZZZ1JZXW0SC001",
        "nr_inmatriculare": "B100AAA",
        "data_prestatie": "2026-06-10",
        "odometru_final": "50000",
        "prestatii": [{"cod_op_service": op, "denumire": op}],
    })

    resp = client.get(f"/_fragments/trimitere/{sid}")
    assert resp.status_code == 200, resp.text[:400]
    html = resp.text

    assert "is-target" in html, (
        f"chip-ul warning al primei operatii nemapate trebuie sa fie tinta la deschiderea initiala: {html[:2000]}"
    )
    assert f"Cod pentru {op} — alege" in html, (
        f"placeholder-ul D2 trebuie sa numeasca operatia tinta la deschiderea initiala: {html[:2000]}"
    )
    select_html = _extrage_select(html)
    assert '<optgroup label="Sugestii">' in select_html, (
        f"optgroup Sugestii trebuie sa apara la deschiderea initiala (fara /form-chips): {select_html[:600]}"
    )
    assert "OE-1" in select_html.split('<optgroup label="Sugestii">')[1].split("</optgroup>")[0], (
        "sugestia fuzzy pentru 'Schimb ulei motor' trebuie sa contina OE-1 chiar la randarea initiala"
    )
    assert "__NEDECLARAT__" in select_html


def _login_seed_ret(client, email: str) -> int:
    """Ca `_login_seed`, dar intoarce account_id (necesar pentru inserarea directa a submission-ului)."""
    acct = _create_account_user(email)
    _login(client, email)
    return acct
