"""Tests for 8 improvements in Gestión 4SAT module:
1) Patente scraper (cache) 2) Buscar-imei predictive 3) Sync-log
4) PUT dispositivo (edit) 5) DELETE usuario 6) PUT config tabla_font_size
"""
import os
import pytest
import requests

BASE_URL = os.environ.get("REACT_APP_BACKEND_URL", "https://doc-manager-111.preview.emergentagent.com").rstrip("/")

ADMIN_EMAIL = "admin4sat@demo.com"
ADMIN_PASSWORD = "Test1234!"


@pytest.fixture(scope="module")
def admin_headers():
    r = requests.post(
        f"{BASE_URL}/api/auth/login",
        json={"email": ADMIN_EMAIL, "password": ADMIN_PASSWORD},
        timeout=15,
    )
    assert r.status_code == 200, f"Login failed: {r.status_code} {r.text}"
    token = r.json()["access_token"]
    return {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}


# ---------- Feature 1: Patente scraper ----------
class TestPatenteScraper:
    def test_bbfl71_returns_cached_data(self, admin_headers):
        r = requests.get(
            f"{BASE_URL}/api/gestion4sat/scraper/patente/BBFL71",
            headers=admin_headers,
            timeout=60,
        )
        assert r.status_code == 200, r.text
        data = r.json()
        assert data.get("patente") == "BBFL71"
        assert data.get("datos") is not None, f"Expected datos payload, got {data}"
        datos = data["datos"]
        # Verify the specific fields the reviewer expects
        assert datos.get("marca", "").upper() == "NISSAN", f"marca mismatch: {datos.get('marca')}"
        assert "TERRANO" in datos.get("modelo", "").upper(), f"modelo mismatch: {datos.get('modelo')}"
        assert str(datos.get("anio", "")).strip() == "2008", f"anio mismatch: {datos.get('anio')}"
        assert datos.get("color", "").upper() == "BLANCO", f"color mismatch: {datos.get('color')}"
        assert datos.get("tipo", "").upper() == "CAMIONETA", f"tipo mismatch: {datos.get('tipo')}"
        # Source should be cache (already scraped previously)
        assert data.get("source") == "cache", f"Expected source=cache, got {data.get('source')}"


# ---------- Feature 2: Predictive IMEI search ----------
class TestBuscarImei:
    def test_buscar_imei_min_chars(self, admin_headers):
        # Less than 3 chars should return empty resultados
        r = requests.get(
            f"{BASE_URL}/api/gestion4sat/dispositivos/buscar-imei?q=86",
            headers=admin_headers,
            timeout=15,
        )
        assert r.status_code == 200, r.text
        assert r.json().get("resultados") == []

    def test_buscar_imei_predictive(self, admin_headers):
        r = requests.get(
            f"{BASE_URL}/api/gestion4sat/dispositivos/buscar-imei?q=866",
            headers=admin_headers,
            timeout=15,
        )
        assert r.status_code == 200, r.text
        data = r.json()
        assert "resultados" in data
        resultados = data["resultados"]
        assert isinstance(resultados, list)
        # Verify all returned items contain '866' in imei
        for item in resultados:
            assert "imei" in item
            assert "866" in item["imei"], f"IMEI {item['imei']} does not contain '866'"
        assert len(resultados) <= 10, "Should limit to 10 results"

    def test_route_precedence_buscar_before_id(self, admin_headers):
        """buscar-imei route MUST be resolved before {dispositivo_id} in FastAPI."""
        r = requests.get(
            f"{BASE_URL}/api/gestion4sat/dispositivos/buscar-imei?q=999",
            headers=admin_headers,
            timeout=15,
        )
        # Should NOT be a 404 from get_dispositivo trying to look up 'buscar-imei' as an id
        assert r.status_code == 200, f"Route precedence broken: {r.status_code} {r.text}"


# ---------- Feature 3: Sync log ----------
class TestSyncLog:
    def test_get_sync_log(self, admin_headers):
        r = requests.get(
            f"{BASE_URL}/api/gestion4sat/sync-log",
            headers=admin_headers,
            timeout=15,
        )
        assert r.status_code == 200, r.text
        data = r.json()
        assert "logs" in data
        assert isinstance(data["logs"], list)


# ---------- Feature 4: PUT dispositivo (edit) ----------
class TestEditDispositivo:
    def test_edit_dispositivo_persists(self, admin_headers):
        # Fetch one dispositivo
        r = requests.get(f"{BASE_URL}/api/gestion4sat/dispositivos?limit=1", headers=admin_headers, timeout=15)
        assert r.status_code == 200
        disps = r.json().get("dispositivos", [])
        if not disps:
            pytest.skip("No dispositivos to test edit")
        disp = disps[0]
        disp_id = disp["id"]
        original_notas = disp.get("notas", "")
        original_patente = disp.get("patente", "")

        test_notas = "TEST_note_from_test_" + disp_id[:8]
        # Update notas
        r = requests.put(
            f"{BASE_URL}/api/gestion4sat/dispositivos/{disp_id}",
            headers=admin_headers,
            json={"notas": test_notas, "vehiculo_marca": "TEST_MARCA"},
            timeout=15,
        )
        assert r.status_code == 200, r.text
        assert r.json().get("ok") is True

        # Verify persistence via GET
        r = requests.get(f"{BASE_URL}/api/gestion4sat/dispositivos/{disp_id}", headers=admin_headers, timeout=15)
        assert r.status_code == 200
        fetched = r.json()
        assert fetched.get("notas") == test_notas, f"notas didn't persist"
        assert fetched.get("vehiculo_marca") == "TEST_MARCA"

        # Restore original values
        requests.put(
            f"{BASE_URL}/api/gestion4sat/dispositivos/{disp_id}",
            headers=admin_headers,
            json={"notas": original_notas, "vehiculo_marca": disp.get("vehiculo_marca", "")},
            timeout=15,
        )

    def test_edit_dispositivo_not_found(self, admin_headers):
        r = requests.put(
            f"{BASE_URL}/api/gestion4sat/dispositivos/nonexistent-id-xxx",
            headers=admin_headers,
            json={"notas": "x"},
            timeout=15,
        )
        assert r.status_code == 404


# ---------- Feature 5: DELETE usuario ----------
class TestDeleteUsuario:
    def test_delete_usuario_flow(self, admin_headers):
        # Create a test user
        import uuid
        test_email = f"TEST_delete_{uuid.uuid4().hex[:8]}@demo.com"
        create_payload = {
            "email": test_email,
            "password": "Test1234!",
            "nombre": "TEST User Delete",
            "rol": "solicitante",
        }
        r = requests.post(f"{BASE_URL}/api/usuarios", headers=admin_headers, json=create_payload, timeout=15)
        if r.status_code not in (200, 201):
            pytest.skip(f"Cannot create test user: {r.status_code} {r.text}")
        created = r.json()
        user_id = created.get("id") or created.get("_id")
        if not user_id:
            # Try listing
            r = requests.get(f"{BASE_URL}/api/usuarios", headers=admin_headers, timeout=15)
            for u in r.json():
                if u.get("email") == test_email:
                    user_id = u.get("id")
                    break
        assert user_id, "Test user creation didn't return id"

        # DELETE
        r = requests.delete(f"{BASE_URL}/api/usuarios/{user_id}", headers=admin_headers, timeout=15)
        assert r.status_code == 200, f"DELETE failed: {r.status_code} {r.text}"

        # Verify user is gone - DELETE the same id again returns 404
        r2 = requests.delete(f"{BASE_URL}/api/usuarios/{user_id}", headers=admin_headers, timeout=15)
        assert r2.status_code == 404, f"Second DELETE should be 404, got {r2.status_code}"


# ---------- Feature 6: PUT config tabla_font_size ----------
class TestConfigFontSize:
    def test_put_config_tabla_font_size(self, admin_headers):
        # Get current config
        r = requests.get(f"{BASE_URL}/api/gestion4sat/config", headers=admin_headers, timeout=15)
        assert r.status_code == 200
        original = r.json().get("tabla_font_size", "normal")

        # Set to large
        r = requests.put(
            f"{BASE_URL}/api/gestion4sat/config",
            headers=admin_headers,
            json={"tabla_font_size": "large"},
            timeout=15,
        )
        assert r.status_code == 200, r.text

        # Verify
        r = requests.get(f"{BASE_URL}/api/gestion4sat/config", headers=admin_headers, timeout=15)
        assert r.status_code == 200
        assert r.json().get("tabla_font_size") == "large"

        # Restore
        requests.put(
            f"{BASE_URL}/api/gestion4sat/config",
            headers=admin_headers,
            json={"tabla_font_size": original},
            timeout=15,
        )
