"""
Parity logging for v1/Gateway comparison during shadow mode.

IMPORTANT: All logging is PII-safe - no raw names, emails, or domains are logged.
Only hashed fingerprints and aggregate metrics are captured.

See: dynamic-purring-sutherland.md for full migration plan.
"""

from __future__ import annotations

import hashlib
import logging
from typing import Any, Dict

logger = logging.getLogger("v1_gateway_parity")


def _safe_hash(value: str) -> str:
    """Create a short hash of a value for fingerprinting without exposing PII."""
    if not value:
        return ""
    return hashlib.md5(value.encode("utf-8", errors="replace")).hexdigest()[:8]


def _safe_fingerprint(source: Dict[str, Any]) -> Dict[str, str]:
    """
    Create a PII-safe fingerprint of a source record.

    Only hashed values are included - no raw PII.
    """
    # Extract and hash identifying fields
    domain = str(
        source.get("Domain") or source.get("Website") or
        source.get("EmailDomain") or source.get("Email") or ""
    ).lower().strip()

    company = str(
        source.get("Company") or source.get("Name") or
        source.get("Account Name") or ""
    ).lower().strip()

    return {
        "domain_hash": _safe_hash(domain),
        "company_hash": _safe_hash(company),
    }


def log_parity(
    *,
    account_id: str,
    request_id: str,
    source: Dict[str, Any],
    candidate_count: int,
    v1_score: float,
    v1_recommendation: str,
    v1_latency_ms: int,
    gateway_score: float,
    gateway_recommendation: str,
    gateway_latency_ms: int,
) -> None:
    """
    Log parity comparison between v1 heuristic and gateway paths.

    This structured log can be queried for parity analysis.
    All PII is hashed - only fingerprints and metrics are logged.

    Example query for parity analysis:
    ```sql
    SELECT
        DATE(timestamp) as day,
        COUNT(*) as requests,
        AVG(score_delta) as avg_score_delta,
        SUM(CASE WHEN recommendation_match THEN 1 ELSE 0 END)::float / COUNT(*) as parity_rate
    FROM logs
    WHERE log_name = 'v1_gateway_parity'
    GROUP BY DATE(timestamp);
    ```
    """
    # Calculate comparison metrics
    score_delta = abs(gateway_score - v1_score)
    recommendation_match = v1_recommendation == gateway_recommendation
    score_improved = gateway_score > v1_score
    score_degraded = gateway_score < (v1_score - 0.05)  # More than 5% drop
    latency_regression = gateway_latency_ms > (v1_latency_ms * 2)  # 2x latency increase

    # Create PII-safe fingerprint
    fingerprint = _safe_fingerprint(source)

    # Log structured parity data
    logger.info(
        "v1_gateway_parity",
        extra={
            # Identifiers (hashed/safe)
            "account_id": account_id,
            "request_id": request_id,
            "fingerprint": fingerprint,

            # Score comparison
            "v1_score": round(v1_score, 4),
            "gateway_score": round(gateway_score, 4),
            "score_delta": round(score_delta, 4),

            # Recommendation comparison
            "v1_recommendation": v1_recommendation,
            "gateway_recommendation": gateway_recommendation,
            "recommendation_match": recommendation_match,

            # Latency comparison
            "v1_latency_ms": v1_latency_ms,
            "gateway_latency_ms": gateway_latency_ms,
            "latency_delta_ms": gateway_latency_ms - v1_latency_ms,

            # Context
            "candidate_count": candidate_count,

            # Aggregate flags for dashboarding
            "score_improved": score_improved,
            "score_degraded": score_degraded,
            "latency_regression": latency_regression,
        }
    )


def should_shadow(account_id: str, request_id: str, sample_pct: int, allowlist: list) -> bool:
    """
    Deterministic sampling decision for shadow mode.

    Uses hash-based sampling so the same account+request always routes
    the same way (no flapping between runs).

    Args:
        account_id: Account identifier
        request_id: Request identifier (idempotency key or similar)
        sample_pct: Percentage of requests to shadow (1-100)
        allowlist: List of account IDs to always shadow

    Returns:
        True if this request should be shadowed
    """
    # Always shadow allowlisted accounts
    if account_id in allowlist:
        return True

    # Deterministic hash-based sampling
    sample_key = f"{account_id}:{request_id}"
    hash_val = int(hashlib.md5(sample_key.encode()).hexdigest()[:8], 16)
    return (hash_val % 100) < sample_pct
