"""Compatibility helpers for legacy payloads and contract results."""

from __future__ import annotations

from typing import Any, Dict, List, Mapping, Optional, Sequence

import pandas as pd

from .mongodb_adapters import build_results_from_report
from .postgres_adapters import build_results_from_dataframe


def build_contract_results_from_legacy_payload(
    payload: Mapping[str, Any],
    *,
    source: str,
    provider: Optional[str] = None,
) -> List[Any]:
    """Build contract results from legacy dict-based payloads.

    The legacy payload remains unchanged and callers can continue returning
    existing summary/top_queries fields while adding contract_results.
    """
    normalized_source = source.lower()

    if normalized_source in {"postgres", "postgresql"}:
        return _build_postgres_contract_results(payload, provider=provider)

    if normalized_source in {"mongo", "mongodb"}:
        return _build_mongodb_contract_results(payload, provider=provider)

    return []


def serialize_contract_results(contract_results: Sequence[Any]) -> List[Any]:
    """Serialize contract objects to JSON-safe dictionaries when possible."""
    serialized: List[Any] = []
    for result in contract_results:
        if hasattr(result, "model_dump"):
            serialized.append(result.model_dump())
        elif isinstance(result, dict):
            serialized.append(result)
        else:
            serialized.append(result)
    return serialized


def _build_postgres_contract_results(
    payload: Mapping[str, Any],
    *,
    provider: Optional[str] = None,
) -> List[Any]:
    summary = payload.get("summary")
    top_queries = payload.get("top_queries")

    if not isinstance(summary, dict):
        summary = {}

    top_queries_df: pd.DataFrame
    if isinstance(top_queries, pd.DataFrame):
        top_queries_df = top_queries
    elif isinstance(top_queries, list):
        top_queries_df = pd.DataFrame(top_queries)
    else:
        return []

    if top_queries_df.empty:
        return []

    recommendations = payload.get("recommendations")
    recommendation_list: Optional[List[str]] = None
    if isinstance(recommendations, list):
        recommendation_list = [str(item) for item in recommendations]

    return build_results_from_dataframe(
        top_queries_df,
        summary,
        recommendations=recommendation_list,
        provider=provider,
    )


def _build_mongodb_contract_results(
    payload: Mapping[str, Any],
    *,
    provider: Optional[str] = None,
) -> List[Any]:
    legacy_slow_queries = payload.get("slow_queries")
    if not isinstance(legacy_slow_queries, list):
        return []

    normalized_slow_queries: List[Dict[str, Any]] = []
    for query in legacy_slow_queries:
        if not isinstance(query, dict):
            continue

        duration_ms = query.get("avg_duration_ms")
        if duration_ms is None:
            duration_ms = query.get("duration_ms")
        if duration_ms is None:
            duration_ms = query.get("millis")

        frequency = query.get("frequency")
        if frequency is None:
            frequency = query.get("count")

        command = query.get("command")
        command_text = None
        if isinstance(command, dict):
            command_text = str(next(iter(command), ""))
        elif command is not None:
            command_text = str(command)

        normalized_slow_queries.append(
            {
                "query_shape": query.get("query_shape") or command_text or "",
                "avg_duration_ms": float(duration_ms or 0.0),
                "impact_score": float(query.get("impact_score") or 0.0),
                "frequency": int(frequency or 1),
                "optimization_suggestions": query.get("optimization_suggestions") or [],
            }
        )

    normalized_report: Dict[str, Any] = {
        "summary": payload.get("summary")
        if isinstance(payload.get("summary"), dict)
        else {},
        "slow_queries": normalized_slow_queries,
        "realtime_metrics": payload.get("realtime_metrics")
        if isinstance(payload.get("realtime_metrics"), dict)
        else {},
        "recommendations": payload.get("recommendations")
        if isinstance(payload.get("recommendations"), list)
        else [],
    }

    return build_results_from_report(normalized_report, provider=provider)
