"""PostgreSQL contract adapters for analyzer outputs."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Dict, List, Optional

import pandas as pd

from ..analyzer import SlowQuery
from .common import map_impact_to_severity, map_provider

if TYPE_CHECKING:
    from iqtoolkit_contracts import AnalysisResultV2, SeverityLevel

    from iqtoolkit_analyzer.postgresql.pgtools_analyzer import (
        PostgreSQLAnalysisResult,
    )


def build_results_from_dataframe(
    top_queries: pd.DataFrame,
    summary: Dict[str, Any],
    recommendations: Optional[List[str]] = None,
    provider: Optional[str] = None,
) -> List["AnalysisResultV2"]:
    """Convert top queries DataFrame into contract results."""
    from iqtoolkit_contracts import (
        AIRecommendation,
        AnalysisFinding,
        AnalysisResultV2,
        DatabaseType,
        QueryInfo,
    )

    results: List[AnalysisResultV2] = []
    mapped_provider = map_provider(provider)

    for index, row in enumerate(top_queries.itertuples(index=False)):
        query_text = str(row.example_query)
        avg_duration = float(getattr(row, "avg_duration", 0.0))
        impact_score = float(getattr(row, "impact_score", 0.0))
        frequency = int(getattr(row, "frequency", 1))

        query_info = QueryInfo(
            query_text=query_text,
            duration_ms=avg_duration,
            source="slow_log",
            database_type=DatabaseType.POSTGRESQL,
        )

        findings = [
            AnalysisFinding(
                name="Slow query",
                description=(
                    f"Average duration {avg_duration:.2f} ms across {frequency} "
                    "executions."
                ),
                severity=map_impact_to_severity(impact_score),
                impact=f"Impact score {impact_score:.2f}",
                fix_suggestion=None,
            )
        ]

        ai_recommendations: List[AIRecommendation] = []
        if (
            mapped_provider is not None
            and recommendations
            and index < len(recommendations)
            and recommendations[index]
        ):
            ai_recommendations.append(
                AIRecommendation(
                    provider=mapped_provider,
                    model=None,
                    recommendation=recommendations[index],
                    confidence=None,
                )
            )

        results.append(
            AnalysisResultV2(
                query=query_info,
                findings=findings,
                recommendations=ai_recommendations,
                severity=map_impact_to_severity(impact_score),
                summary={
                    "summary": summary,
                    "frequency": frequency,
                    "impact_score": impact_score,
                },
            )
        )

    return results


def build_results_from_slow_queries(
    slow_queries: List[SlowQuery],
    provider: Optional[str] = None,
) -> List["AnalysisResultV2"]:
    """Convert SlowQuery objects into contract results."""
    from iqtoolkit_contracts import (
        AIRecommendation,
        AnalysisFinding,
        AnalysisResultV2,
        DatabaseType,
        QueryInfo,
    )

    results: List[AnalysisResultV2] = []
    mapped_provider = map_provider(provider)

    for query in slow_queries:
        query_info = QueryInfo(
            query_text=query.normalized_query,
            duration_ms=query.duration,
            source="slow_log",
            database_type=DatabaseType.POSTGRESQL,
        )

        findings = [
            AnalysisFinding(
                name="Slow query",
                description=(
                    f"Average duration {query.duration:.2f} ms across "
                    f"{query.frequency} executions."
                ),
                severity=map_impact_to_severity(query.impact_score),
                impact=f"Impact score {query.impact_score:.2f}",
                fix_suggestion=None,
            )
        ]

        ai_recommendations: List[AIRecommendation] = []
        if mapped_provider is not None:
            # Placeholder for future AI integration in this pathway.
            ai_recommendations = []

        results.append(
            AnalysisResultV2(
                query=query_info,
                findings=findings,
                recommendations=ai_recommendations,
                severity=map_impact_to_severity(query.impact_score),
                summary={"frequency": query.frequency},
            )
        )

    return results


def build_results_from_pgtools(
    result: "PostgreSQLAnalysisResult",
    provider: Optional[str] = None,
    ai_recommendations: Optional[str] = None,
) -> List["AnalysisResultV2"]:
    """Convert pgtools analysis result into contract results."""
    from iqtoolkit_contracts import (
        AIRecommendation,
        AnalysisFinding,
        AnalysisResultV2,
        DatabaseType,
        QueryInfo,
        SeverityLevel,
    )

    findings: List[AnalysisFinding] = []
    for rec in result.recommendations:
        severity = _map_pgtools_severity(rec.severity, SeverityLevel)
        findings.append(
            AnalysisFinding(
                name=rec.title,
                description=rec.description,
                severity=severity,
                impact=rec.metric,
                fix_suggestion=rec.suggestion,
            )
        )

    ai_results: List[AIRecommendation] = []
    mapped_provider = map_provider(provider)
    if mapped_provider is not None and ai_recommendations:
        ai_results.append(
            AIRecommendation(
                provider=mapped_provider,
                model=None,
                recommendation=ai_recommendations,
                confidence=None,
            )
        )

    query_info = QueryInfo(
        query_text="pgtools_analysis",
        duration_ms=None,
        source="pgtools",
        database_type=DatabaseType.POSTGRESQL,
    )

    summary = {
        "tables": result.settings.tables_count,
        "indexes": result.settings.indexes_count,
        "extensions": len(result.settings.extensions),
        "slow_queries": len(result.slow_queries),
        "locks": len(result.locks),
        "connections": len(result.connections),
        "issues_found": result.issues_found,
    }

    severity = _overall_severity(findings, SeverityLevel)

    return [
        AnalysisResultV2(
            query=query_info,
            findings=findings,
            recommendations=ai_results,
            severity=severity,
            summary=summary,
        )
    ]


def _map_pgtools_severity(severity: str, levels: Any) -> "SeverityLevel":
    normalized = severity.lower()
    if normalized == "critical":
        return levels.CRITICAL
    if normalized == "warning":
        return levels.HIGH
    if normalized == "info":
        return levels.LOW
    return levels.MEDIUM


def _overall_severity(findings: List[Any], levels: Any) -> "SeverityLevel":
    if not findings:
        return levels.INFO

    severity_order = [
        levels.CRITICAL,
        levels.HIGH,
        levels.MEDIUM,
        levels.LOW,
        levels.INFO,
    ]

    for level in severity_order:
        if any(finding.severity == level for finding in findings):
            return level

    return levels.INFO
