"""
Tests for the saving-scan funnel endpoint.

Focus: input validation + lead persistence + rate-limit error path.
The actual compliance check is mocked — we only verify the route layer.
"""

import os
import sys
from unittest.mock import patch

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

# Use a temp SQLite for the sidecar
os.environ["COMPLIANCE_AUDIT_DB"] = "/tmp/test_saving_scan.db"
if os.path.exists("/tmp/test_saving_scan.db"):
    os.remove("/tmp/test_saving_scan.db")

from compliance.api.saving_scan_routes import router  # noqa: E402

app = FastAPI()
app.include_router(router, prefix="/api")
client = TestClient(app)


class TestStartSavingScanValidation:

    def test_missing_email_returns_422(self):
        resp = client.post("/api/compliance/agent/saving-scan/start",
                           json={"url": "https://example.de"})
        assert resp.status_code == 422

    def test_invalid_email_returns_400(self):
        with patch("compliance.api.saving_scan_routes.asyncio.create_task"):
            resp = client.post(
                "/api/compliance/agent/saving-scan/start",
                json={"url": "https://example.de", "email": "kein-email",
                      "consent": True},
            )
            assert resp.status_code == 400
            assert "E-Mail" in resp.json()["detail"]

    def test_invalid_url_returns_400(self):
        with patch("compliance.api.saving_scan_routes.asyncio.create_task"):
            resp = client.post(
                "/api/compliance/agent/saving-scan/start",
                json={"url": "ftp://wrong.de", "email": "u@x.de",
                      "consent": True},
            )
            assert resp.status_code == 400

    def test_consent_required(self):
        with patch("compliance.api.saving_scan_routes.asyncio.create_task"):
            resp = client.post(
                "/api/compliance/agent/saving-scan/start",
                json={"url": "https://example.de", "email": "u@x.de",
                      "consent": False},
            )
            assert resp.status_code == 400
            assert "Consent" in resp.json()["detail"]


def _patch_check_runner():
    """Stub the lazy-imported worker — avoids loading smtp_sender (Py3.10+)."""
    import sys, types
    fake = types.ModuleType("compliance.api.agent_compliance_check_routes")

    class _DocInput:
        def __init__(self, doc_type="other", url=""): self.doc_type, self.url = doc_type, url

    class _Req:
        def __init__(self, **kw): self.__dict__.update(kw)

    async def _runner(*_a, **_kw): pass

    fake.DocumentInput = _DocInput
    fake.ComplianceCheckRequest = _Req
    fake._run_compliance_check = _runner
    fake._compliance_check_jobs = {}
    sys.modules["compliance.api.agent_compliance_check_routes"] = fake


class TestStartSavingScanSuccess:

    def test_valid_request_starts_check(self):
        _patch_check_runner()
        resp = client.post(
            "/api/compliance/agent/saving-scan/start",
            json={"url": "https://example-newdomain.de",
                  "email": "user@example.de", "consent": True},
        )
        assert resp.status_code == 200, resp.text
        data = resp.json()
        assert "check_id" in data
        assert data["status"] == "running"
        assert "example-newdomain.de" in data["message"]


class TestLeadCount:

    def test_lead_count_after_submit(self):
        _patch_check_runner()
        client.post(
            "/api/compliance/agent/saving-scan/start",
            json={"url": "https://abc-leadtest.de",
                  "email": "lead@x.de", "consent": True},
        )
        resp = client.get("/api/compliance/agent/saving-scan/lead-count")
        assert resp.status_code == 200
        data = resp.json()
        assert data["total_leads"] >= 1
        assert "abc-leadtest.de" in str(data["top_domains"])
