"""Teste pentru auto-refresh dupa actiuni proprii pe lista de trimiteri.

Comportament:
  1. Dupa actiune proprie (mapare inline, corectie, repune, commit), lista
     Trimiteri se reincarca automat, fara click pe Reincarca.
     Mecanism: server emite HX-Trigger: trimiteriChanged; #submissions-wrap
     asculta 'trimiteriChanged from:body' si re-fetches imediat.
  2. Filtrul activ si pagina curenta NU se reseteaza la auto-refresh.
     Mecanism: hx-include="#filtre-trimiteri" pe #submissions-wrap.
  3. Pollerul de fundal face auto-refresh direct la date noi (versiune diferita),
     fara nudge intermediar: distinctia intre schimbare proprie si externa nu e
     posibila pe client fara sesiune dedicata, iar auto-refresh e mai simplu.
  4. Elementul #nudge-trimiteri e eliminat din template.
"""

from __future__ import annotations

import json
import os
import tempfile

import pytest
from fastapi.testclient import TestClient


# --------------------------------------------------------------------------- #
# Fixture                                                                       #
# --------------------------------------------------------------------------- #

@pytest.fixture()
def client(monkeypatch):
    tmp = tempfile.mkdtemp()
    monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "us008.db"))
    monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "false")
    from app.config import get_settings
    get_settings.cache_clear()
    from app.main import app
    with TestClient(app) as c:
        yield c
    get_settings.cache_clear()


def _add_submission(account_id: int = 1, status: str = "queued", payload: dict | None = None) -> int:
    """Adauga un submission si returneaza id-ul sau.

    status: starea dorita (implicit 'queued'); use 'needs_mapping' pentru testele de mapare.
    payload: continut JSON (implicit minimal).
    """
    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"us008_key_{account_id}_{status}", account_id, status,
             json.dumps(payload or {"test": True})),
        )
        return cur.lastrowid
    finally:
        conn.close()


def _add_nomenclator(cod: str = "R-FRANE", nume: str = "Reparatie frane") -> None:
    """Insereaza un cod RAR in nomenclatorul local."""
    from app.db import get_connection
    conn = get_connection()
    try:
        conn.execute(
            "INSERT OR REPLACE INTO nomenclator_rar (cod_prestatie, nume_prestatie) VALUES (?,?)",
            (cod, nume),
        )
    finally:
        conn.close()


def test_submissions_wrap_reincarca_la_trimiteriChanged(client):
    """#submissions-wrap se reincarca automat la evenimentul trimiteriChanged.

    Actiunile proprii (mapare inline, corectie, repune, commit) emit
    HX-Trigger: trimiteriChanged. #submissions-wrap asculta
    'trimiteriChanged from:body' si re-fetches imediat, fara click pe Reincarca.

    Nota: _coada.html se randeaza doar cand exista submission-uri (are_trimiteri=True).
    Semanarea unui submission inainte de GET garanteaza randarea sectionii complete.
    """
    _add_submission()

    r = client.get("/_fragments/acasa")
    assert r.status_code == 200, r.text

    assert "submissions-wrap" in r.text, (
        "#submissions-wrap lipseste din /_fragments/acasa (cu submission existent)"
    )
    assert "trimiteriChanged from:body" in r.text, (
        "#submissions-wrap nu asculta 'trimiteriChanged from:body' — "
        "auto-refresh dupa actiuni proprii nu va functiona"
    )


def test_submissions_wrap_pastreaza_filtrul_la_auto_refresh(client):
    """Auto-refresh-ul nu reseteaza filtrul activ sau pagina curenta.

    #submissions-wrap include #filtre-trimiteri la fiecare request HTMX.
    La reincarcarea declansata de trimiteriChanged, filtrul curent (stare,
    vehicul, data) si pagina curenta se retransmit automat.
    """
    _add_submission()

    r = client.get("/_fragments/acasa")
    assert r.status_code == 200, r.text

    html = r.text
    assert 'hx-include="#filtre-trimiteri"' in html or "hx-include='#filtre-trimiteri'" in html, (
        "hx-include=#filtre-trimiteri lipseste din #submissions-wrap — "
        "filtrul se va reseta la auto-refresh"
    )


def test_poller_auto_refresh_nu_nudge(client):
    """Pollerul de fundal face auto-refresh la date noi, NU afiseaza nudge.

    Cand versiunea difera, pollerul cheama reincarcaTrimiteri() care re-fetches
    #submissions-wrap pastrand filtrul curent, in loc sa arate un nudge.
    """
    r = client.get("/")
    assert r.status_code == 200, r.text
    html = r.text

    assert "nudge.hidden = false" not in html, (
        "Pollerul inca arata nudge in loc de auto-refresh — "
        "schimbati 'nudge.hidden = false' cu 'reincarcaTrimiteri()' in base.html"
    )


def test_nudge_eliminat_din_lista(client):
    """Elementul #nudge-trimiteri este eliminat din template-ul listei.

    Semanarea unui submission asigura ca _coada.html e inclus in raspuns
    (altfel testul ar pasa vacuos).
    """
    _add_submission()

    r = client.get("/_fragments/acasa")
    assert r.status_code == 200, r.text

    assert "nudge-trimiteri" not in r.text, (
        "#nudge-trimiteri inca exista in template — "
        "eliminati elementul din _coada.html dupa ce pollerul e migrat la auto-refresh"
    )


def test_actiune_proprie_reincarca_automat(client):
    """Dupa o actiune proprie (mapare inline), lista se reincarca automat.

    Verifica doua componente ale mecanismului:
      1. Server-side: POST la mapare inline returneaza HX-Trigger: trimiteriChanged.
      2. Client-side: #submissions-wrap asculta 'trimiteriChanged from:body' si
         declanseaza re-fetch imediat la primirea headerului.

    Testeaza calea mapare-inline; corectie/repune/commit sunt acoperite similar
    (verificate in test_import_commit.py).
    """
    _add_nomenclator("R-FRANE", "Reparatie frane")
    sub_id = _add_submission(
        status="needs_mapping",
        payload={"prestatii": [{"cod_op_service": "OP-FRANE"}]},
    )

    r = client.post(
        f"/trimitere/{sub_id}/mapeaza",
        data={"csrf_token": "", "cod_op_service": "OP-FRANE", "cod_prestatie": "R-FRANE"},
    )
    assert r.status_code == 200, r.text

    hx = r.headers.get("HX-Trigger", "")
    assert "trimiteriChanged" in hx, (
        f"Mapare inline nu emite HX-Trigger: trimiteriChanged — "
        f"lista nu se va reincarca automat. Header primit: {hx!r}"
    )

    r_acasa = client.get("/_fragments/acasa")
    assert "trimiteriChanged from:body" in r_acasa.text, (
        "#submissions-wrap nu asculta 'trimiteriChanged from:body' — "
        "auto-refresh nu va functiona dupa actiune proprie"
    )


def test_nudge_nu_mai_blocheaza_actualizarea(client):
    """Nudge-ul 'Date noi. Reincarca' nu mai poate bloca actualizarea listei.

    Pollerul cheama direct reincarcaTrimiteri() la versiune diferita —
    actualizare automata, fara ca utilizatorul sa trebuiasca sa apese un buton.
    """
    _add_submission()

    r_pagina = client.get("/_fragments/acasa")
    assert r_pagina.status_code == 200, r_pagina.text
    html = r_pagina.text

    assert "nudge-trimiteri" not in html, (
        "#nudge-trimiteri inca exista — poate bloca actualizarea listei"
    )

    r_home = client.get("/")
    assert r_home.status_code == 200, r_home.text
    assert "nudge.hidden = false" not in r_home.text, (
        "Pollerul JS inca poate afisa nudge-ul — schimbati cu reincarcaTrimiteri()"
    )

    assert "reincarcaTrimiteri" in r_home.text, (
        "reincarcaTrimiteri() lipseste din poller — auto-refresh nu va functiona"
    )
