"""Teste US-014 (PRD 5.10): Selector de tema ciclic Light/Dark/Petrol/Auto.

TDD: testele se scriu INAINTE de implementare (RED), dupa implementare trec (GREEN).

Testeaza:
- test_petrol_theme_definit: [data-theme="petrol"] definit cu valorile din DESIGN.md
- test_buton_cicleaza_temele: buton ciclic + anti-FOUC extins + aria-live
"""

from __future__ import annotations

import os
import re
import tempfile

import pytest
from starlette.testclient import TestClient


@pytest.fixture()
def client(monkeypatch):
    tmp = tempfile.mkdtemp()
    monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "selector.db"))
    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 _get_style(html: str) -> str:
    m = re.search(r"<style>(.*?)</style>", html, re.DOTALL)
    assert m, "<style> negasit in HTML"
    return m.group(1)


def _get_head(html: str) -> str:
    m = re.search(r"<head>(.*?)</head>", html, re.DOTALL | re.IGNORECASE)
    assert m, "<head> negasit in HTML"
    return m.group(1)


# ── test_petrol_theme_definit ─────────────────────────────────────────────────

def test_petrol_theme_definit(client):
    """[data-theme="petrol"] definit in CSS cu valorile din DESIGN.md:
    --bg:#0e1416, --card:#161e20, --ink:#e6e9ef, --muted:#8b93a7,
    --line:#232c2e, --accent:#0E7C7B, --ok:#2FBF8F, --warn:#E0A93B, --err:#E05D5D
    """
    resp = client.get("/login")
    assert resp.status_code == 200
    style = _get_style(resp.text)

    # Bloc CSS [data-theme="petrol"] prezent
    petrol_m = re.search(
        r'\[data-theme=["\']petrol["\']\]\s*\{([^}]+)\}',
        style,
        re.DOTALL,
    )
    assert petrol_m, (
        '[data-theme="petrol"] { ... } negasit in <style>. '
        "Tema Petrol trebuie definita conform DESIGN.md."
    )
    petrol_block = petrol_m.group(1)

    petrol_vars = {
        "--accent": "#0E7C7B",
        "--bg": "#0e1416",
        "--card": "#161e20",
        "--ink": "#e6e9ef",
        "--line": "#232c2e",
        "--ok": "#2FBF8F",
        "--warn": "#E0A93B",
        "--err": "#E05D5D",
    }
    for var, val in petrol_vars.items():
        assert val.lower() in petrol_block.lower(), (
            f"Variabila {var}:{val} lipseste din [data-theme=\"petrol\"]. "
            f"Block petrol: {petrol_block.strip()}"
        )


# ── test_buton_cicleaza_temele ────────────────────────────────────────────────

def test_buton_cicleaza_temele(client):
    """Butonul de tema cicleaza Light->Dark->Petrol->Auto si are accesibilitate completa.

    Verifica:
    1. Anti-FOUC extins: cunoaste 'petrol' si 'auto'; fallback definit pt. valori legacy
    2. JS-ul ciclului contine toate cele 4 teme in ordinea corecta
    3. aria-label pe buton include 'Tema:' + tema curenta + urmatoarea
    4. Regiune aria-live="polite" prezenta pentru anuntarea schimbarii
    """
    resp = client.get("/login")
    assert resp.status_code == 200
    html = resp.text
    head = _get_head(html)

    # 1. Anti-FOUC cunoaste 'petrol' si 'auto' (script in <head>, inainte de <style>)
    style_pos = head.find('<style>')
    assert style_pos >= 0, "<style> negasit in <head>"
    head_before_style = head[:style_pos]

    assert 'petrol' in head_before_style, (
        "Scriptul anti-FOUC nu cunoaste tema 'petrol'. "
        "Trebuie extins sa enumere toate cele 4 teme (light/dark/petrol/auto)."
    )
    assert 'auto' in head_before_style, (
        "Scriptul anti-FOUC nu cunoaste tema 'auto'. "
        "Trebuie sa rezolve 'auto' la light/dark inainte de primul paint."
    )

    # 2. Anti-FOUC are fallback pentru valori legacy/necunoscute (un set de valide)
    # Acceptam: un obiect/array VALID, sau un if care verifica valorile cunoscute
    has_valid_guard = (
        'VALID' in head_before_style
        or re.search(r'light.*dark.*petrol.*auto', head_before_style, re.DOTALL)
        or 'indexOf' in head_before_style
    )
    assert has_valid_guard, (
        "Anti-FOUC lipseste de un guard pentru valori legacy/necunoscute. "
        "O valoare 'localStorage.theme' necunoscuta trebuie sa cada pe 'auto' sau 'dark'."
    )

    # 3. JS-ul din <body> contine ciclul complet Light->Dark->Petrol->Auto
    # Cautam in tot HTML-ul (nu doar head) prezenta tuturor celor 4 teme in JS
    # Acceptam: array explicit ['light','dark','petrol','auto'] sau logic echivalent
    cycle_match = re.search(
        r"['\"]light['\"].*['\"]dark['\"].*['\"]petrol['\"].*['\"]auto['\"]",
        html,
        re.DOTALL,
    )
    assert cycle_match, (
        "Ciclul Light->Dark->Petrol->Auto negasit in JS. "
        "Asteptat: array sau secventa cu toate cele 4 teme in ordine."
    )

    # 4. aria-label pe butonul tema-toggle include 'Tema:' (format 'Tema: X, apasa pentru Y')
    tema_btn = re.search(
        r'<button[^>]+id=["\']tema-toggle["\'][^>]*>',
        html,
        re.IGNORECASE,
    )
    assert tema_btn, "Butonul #tema-toggle negasit in HTML"
    btn_tag = tema_btn.group(0)
    # Acceptam aria-label setat initial in HTML SAU prin JS (aria-label din tag poate fi
    # placeholder; testam ca JS-ul contine formatul corect)
    has_tema_label = (
        'Tema:' in html
        or 'tema:' in html.lower()
        or re.search(r'aria-label[^>]*[Tt]ema', html)
    )
    assert has_tema_label, (
        "aria-label cu formatul 'Tema: ...' negasit in HTML/JS. "
        "Butonul trebuie sa anunte tema curenta + urmatoarea."
    )

    # 5. Regiune aria-live="polite" prezenta (pentru anuntarea schimbarii de tema)
    assert 'aria-live="polite"' in html or "aria-live='polite'" in html, (
        'Regiune aria-live="polite" negasita in HTML. '
        "Necesara pentru a anunta schimbarea temei catre screen-readers."
    )

    # 6. US-014b (decizie user): title-ul vizual al butonului = DOAR numele temei, NU ciclul.
    # Verificam in sursa JS ca variabila TOOLTIP_CICLU (sirul cu "Ciclu: Light → Dark → ...") nu
    # mai e folosita in title. aria-label-ul informativ (curenta+urmatoarea) RAMANE neschimbat.
    assert 'TOOLTIP_CICLU' not in html, (
        "Variabila TOOLTIP_CICLU inca prezenta in JS — title-ul trebuie simplificat. "
        "US-014b: btn.title trebuie sa fie DOAR LABELS[s] (ex. 'Light'), "
        "nu 'Tema: X. Ciclu: Light -> Dark -> Petrol -> Auto'. "
        "aria-label-ul informativ RAMANE neschimbat."
    )
    # Verifica ca JS-ul seteaza btn.title la doar LABELS[s] (fara prefix 'Tema:' sau ciclul)
    assert re.search(r"btn\.title\s*=\s*LABELS\[", html), (
        "btn.title nu e setat la LABELS[s] in JS. "
        "US-014b: formatul asteptat: btn.title = LABELS[s]  (ex. rezultat: 'Petrol'). "
        "Aria-label-ul informativ ramane separat: 'Tema: X, apasa pentru Y'."
    )
