"""
Voll-Audit Findings Router — unified view across all 4 finding sources.

Endpoint:
  GET /api/compliance/agent/findings/{check_id}
      ?source=mc|pflichtangabe|vendor|redundanz|all
      &severity=CRITICAL|HIGH|MEDIUM|LOW|INFO|all
      &doc_type=impressum|dse|cookie|...|all
      &status=failed|passed|skipped|na|info|all
      &q=<freitext>
      &limit=<int>

Liefert summary + filtered findings list. Frontend rendert daraus den
Voll-Audit-Tab unter /sdk/agent/audit/<check_id>.
"""

from __future__ import annotations

import logging
from urllib.parse import urlparse
from fastapi import APIRouter, HTTPException, Query

from compliance.services.unified_findings_store import (
    findings_summary,
    list_findings,
)
from compliance.services.compliance_audit_log import get_check_run, get_check_payload

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/compliance/agent", tags=["agent"])


def _normalize_domain(d: str) -> str:
    if not d:
        return ""
    if "://" not in d:
        d = "https://" + d
    host = urlparse(d).netloc.lower()
    return host[4:] if host.startswith("www.") else host


@router.get("/findings/{check_id}")
def get_findings(
    check_id: str,
    source: str | None = Query(None, description="mc|pflichtangabe|vendor|redundanz|all"),
    severity: str | None = Query(None, description="CRITICAL|HIGH|MEDIUM|LOW|INFO|all"),
    doc_type: str | None = Query(None),
    status: str | None = Query(None, description="failed|passed|skipped|na|info|all"),
    q: str | None = Query(None, description="freitext-suche label/vendor"),
    limit: int = Query(1000, ge=1, le=5000),
    expected_domain: str | None = Query(
        None, description="Hard-Assertion: Run muss zu dieser Domain gehoeren (Cross-Tenant-Schutz)",
    ),
) -> dict:
    """Return aggregated findings + summary counters for a check run."""
    # P7-Restpunkt: optionale Domain-Assertion. Verhindert dass ein Frontend
    # einen check_id einer fremden Tenant-Domain anfragen kann.
    if expected_domain:
        run = get_check_run(check_id)
        actual = _normalize_domain((run or {}).get("base_domain") or "")
        if not run or actual != _normalize_domain(expected_domain):
            raise HTTPException(
                status_code=403,
                detail=f"Cross-tenant access blocked: check_id {check_id} "
                       f"gehoert zu Domain '{actual or '?'}', angefragt: "
                       f"'{_normalize_domain(expected_domain)}'",
            )
    try:
        summary = findings_summary(check_id)
        findings = list_findings(
            check_id=check_id,
            source_type=source,
            severity=severity,
            doc_type=doc_type,
            status=status,
            q=q,
            limit=limit,
        )
        return {
            "found": summary.get("total", 0) > 0,
            "check_id": check_id,
            "summary": summary,
            "filter": {
                "source": source or "all",
                "severity": severity or "all",
                "doc_type": doc_type or "all",
                "status": status or "all",
                "q": q or "",
                "limit": limit,
            },
            "count": len(findings),
            "findings": findings,
        }
    except Exception as e:
        logger.exception("get_findings failed for %s", check_id)
        return {
            "found": False,
            "check_id": check_id,
            "error": str(e)[:200],
            "summary": {},
            "count": 0,
            "findings": [],
        }


@router.get("/banner/{check_id}")
def get_banner_payload(check_id: str) -> dict:
    """P20: full banner_result (phases, structured_checks, category_tests,
    banner_checks.violations) fuer das Voll-Audit-Frontend.
    """
    try:
        payload = get_check_payload(check_id) or {}
        banner = payload.get("banner") or {}
        return {"found": bool(banner), "check_id": check_id, "banner": banner}
    except Exception as e:
        logger.exception("get_banner_payload failed for %s", check_id)
        return {"found": False, "check_id": check_id,
                "error": str(e)[:200], "banner": {}}
