"""Teste US-001 (PRD 5.12): companie/email/CUI obligatorii la signup.

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

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, "test_signup_us001.db"))
    monkeypatch.setenv("AUTOPASS_SIGNUP_RATE_MAX", "100")
    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) as c:
        yield c
    get_settings.cache_clear()


def _csrf(html: str) -> str:
    m = re.search(r'name="csrf_token"\s+value="([^"]+)"', html)
    if not m:
        m = re.search(r'value="([^"]+)"\s+name="csrf_token"', html)
    assert m, "csrf_token negasit in HTML"
    return m.group(1)


def test_signup_html_cui_obligatoriu_ui(client):
    """GET /signup: campul CUI NU contine '(optional)' si are atribut required (US-001 UI)."""
    resp = client.get("/signup")
    assert resp.status_code == 200
    # (a) NU trebuie sa apara textul "(optional)" langa CUI
    assert "(optional)" not in resp.text, "Campul CUI afiseaza '(optional)' — trebuie sa fie obligatoriu"
    # (b) input[name=cui] trebuie sa aiba atribut required
    assert 'name="cui"' in resp.text
    # cautam required pe aceeasi linie cu name="cui" sau intr-un bloc care contine name="cui" required
    import re
    # fie pe aceeasi linie: <input ... name="cui" ... required ...>
    # fie in orice forma cu required si name="cui" in acelasi tag
    cui_input_match = re.search(r'<input[^>]*name="cui"[^>]*>', resp.text)
    assert cui_input_match, "input name='cui' negasit in HTML"
    assert "required" in cui_input_match.group(0), (
        f"input[name='cui'] NU are atribut required: {cui_input_match.group(0)}"
    )


def test_signup_fara_cui_422(client):
    """POST /signup fara CUI -> 422, formular re-randat cu eroare, fara cont creat."""
    resp = client.get("/signup")
    token = _csrf(resp.text)

    resp = client.post("/signup", data={
        "name": "Service Fara CUI",
        "cui": "",
        "email": "fara_cui@test.com",
        "parola": "parolasecreta123",
        "consent": "1",
        "csrf_token": token,
    })
    # trebuie sa returneze 422 (sau sa randeze formularul cu eroare)
    assert resp.status_code == 422
    # cheia API nu trebuie sa apara
    assert "rfak_" not in resp.text
    # campul name trebuie sa fie pastrat (form re-render cu valorile existente)
    assert "Service Fara CUI" in resp.text

    # verifica ca nu s-a creat niciun cont
    from app.db import get_connection
    conn = get_connection()
    try:
        n = conn.execute(
            "SELECT COUNT(*) AS n FROM accounts WHERE name='Service Fara CUI'"
        ).fetchone()["n"]
        assert n == 0, "Cont creat desi CUI lipsea"
    finally:
        conn.close()


def test_signup_scrie_email_pe_account(client):
    """POST /signup valid -> accounts.email = emailul utilizatorului."""
    resp = client.get("/signup")
    token = _csrf(resp.text)

    resp = client.post("/signup", data={
        "name": "Service Cu Email",
        "cui": "RO9999001",
        "email": "cu_email@test.com",
        "parola": "parolasecreta123",
        "consent": "1",
        "csrf_token": token,
    })
    assert resp.status_code == 200
    assert "rfak_" in resp.text

    from app.db import get_connection
    conn = get_connection()
    try:
        acct = conn.execute(
            "SELECT * FROM accounts WHERE name='Service Cu Email'"
        ).fetchone()
        assert acct is not None
        # emailul trebuie scris pe cont (normalizat: lower + trim)
        assert acct["email"] == "cu_email@test.com"
    finally:
        conn.close()


def test_signup_email_duplicat_mesaj_email(client):
    """POST /signup cu email existent dar CUI nou -> mesaj despre EMAIL, NU despre CUI/firma.

    Bug: 'email deja folosit' contine 'deja folosit' -> era prins de conditia CUI duplicat
    si afisa gresit 'Aceasta firma (CUI X) e deja inregistrata' (CUI nou, NU cauza reala).
    Fix: verifica intai email-ul, apoi CUI-ul.
    """
    from tests.conftest import make_test_cui

    # primul signup cu email E + CUI C1
    resp = client.get("/signup")
    token = _csrf(resp.text)
    resp1 = client.post("/signup", data={
        "name": "Firma Prima SRL",
        "cui": make_test_cui("email-dup-c1"),
        "email": "emaildup@test.com",
        "parola": "parolasecreta123",
        "consent": "1",
        "csrf_token": token,
    })
    assert resp1.status_code == 200
    assert "rfak_" in resp1.text, "Primul signup trebuia sa reuseasca"

    # al doilea signup cu ACELASI email dar CUI NOU
    resp = client.get("/signup")
    token2 = _csrf(resp.text)
    cui_nou = make_test_cui("email-dup-c2")
    resp2 = client.post("/signup", data={
        "name": "Firma A Doua SRL",
        "cui": cui_nou,
        "email": "emaildup@test.com",
        "parola": "parolasecreta456",
        "consent": "1",
        "csrf_token": token2,
    })

    assert resp2.status_code in (200, 422)
    assert "rfak_" not in resp2.text, "Nu trebuia creata cheie API la email duplicat"

    body_lower = resp2.text.lower()
    # mesajul trebuie sa se refere la EMAIL
    assert "email" in body_lower, (
        f"Mesajul de eroare nu mentioneaza 'email': {resp2.text[:500]}"
    )
    # mesajul NU trebuie sa afiseze pattern-ul gresit cu firma si CUI-ul nou
    # (CUI-ul apare legitim si in campul pre-completat al formularului, dar nu in mesajul de eroare)
    wrong_pattern = f"(cui {cui_nou.lower()}) e deja inregistrata"
    assert wrong_pattern not in body_lower, (
        f"Mesajul arata gresit pattern-ul CUI-duplicat desi problema e emailul: {resp2.text[:500]}"
    )
    # nu trebuie sa apara mesajul specific CUI-duplicat
    assert "e deja inregistrata" not in body_lower, (
        f"Mesajul arata 'e deja inregistrata' (mesaj CUI) la eroare de email: {resp2.text[:500]}"
    )


def test_signup_cui_existent_mesaj_prietenos(client):
    """POST /signup cu CUI existent -> mesaj prietenos, NU mesaj tehnic cu 'activate --account'."""
    resp = client.get("/signup")
    token = _csrf(resp.text)

    # primul signup
    client.post("/signup", data={
        "name": "Firma Existenta SRL",
        "cui": "RO8888001",
        "email": "firma1@test.com",
        "parola": "parolasecreta123",
        "consent": "1",
        "csrf_token": token,
    })

    # al doilea signup cu acelasi CUI
    resp = client.get("/signup")
    token2 = _csrf(resp.text)
    resp2 = client.post("/signup", data={
        "name": "Alt Utilizator SRL",
        "cui": "RO8888001",
        "email": "firma2@test.com",
        "parola": "parolasecreta456",
        "consent": "1",
        "csrf_token": token2,
    })

    assert resp2.status_code in (200, 422)
    # NU trebuie sa apara mesajul tehnic cu referinta la CLI
    assert "activate --account" not in resp2.text
    # trebuie sa apara un mesaj prietenos cu CUI-ul
    assert "RO8888001" in resp2.text
    # trebuie sa contina cuvant cheie de tip "firma" sau "inregistrata"
    body_lower = resp2.text.lower()
    assert any(kw in body_lower for kw in ["firma", "inregistrat", "cont", "acces"])
