"""Correlate production incidents with code hotspots.

Maps incident data to specific files/modules to identify which
areas of the codebase are causing the most production issues.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any

from ..store import DebtStore


@dataclass
class IncidentHotspot:
    """A code location correlated with incidents."""

    file_path: str
    incident_count: int
    weighted_score: float
    complexity_score: float = 0.0
    correlation_strength: float = 0.0  # 0-1

    def to_dict(self) -> dict[str, Any]:
        return {
            "file_path": self.file_path,
            "incident_count": self.incident_count,
            "weighted_score": round(self.weighted_score, 2),
            "complexity_score": round(self.complexity_score, 2),
            "correlation_strength": round(self.correlation_strength, 3),
        }


class IncidentCorrelator:
    """Correlate incidents with code quality metrics."""

    def __init__(self, store: DebtStore) -> None:
        self.store = store

    def record_incident(
        self,
        repo_path: str,
        file_path: str,
        incident_id: str,
        severity: str = "medium",
        description: str = "",
    ) -> None:
        """Record a production incident linked to a file."""
        self.store.record_incident(
            repo_path=repo_path,
            file_path=file_path,
            incident_id=incident_id,
            severity=severity,
            description=description,
        )

    def get_hotspots(
        self,
        repo_path: str,
        complexity_scores: dict[str, float] | None = None,
        limit: int = 20,
    ) -> list[IncidentHotspot]:
        """Get files with the most incidents, enriched with complexity data.

        Args:
            repo_path: Repository path to query.
            complexity_scores: Optional dict of file_path -> complexity score.
            limit: Max results.
        """
        raw_hotspots = self.store.get_incident_hotspots(repo_path, limit)
        complexity_scores = complexity_scores or {}

        results: list[IncidentHotspot] = []
        max_weighted = max(
            (h["weighted_score"] for h in raw_hotspots), default=1.0
        ) or 1.0

        for h in raw_hotspots:
            fp = h["file_path"]
            cx = complexity_scores.get(fp, 0.0)

            # Correlation: high incidents + high complexity = strong correlation
            incident_norm = h["weighted_score"] / max_weighted
            complexity_norm = min(1.0, cx / 50.0)  # 50+ complexity = max
            correlation = (incident_norm * 0.6 + complexity_norm * 0.4)

            results.append(
                IncidentHotspot(
                    file_path=fp,
                    incident_count=h["incident_count"],
                    weighted_score=h["weighted_score"],
                    complexity_score=cx,
                    correlation_strength=correlation,
                )
            )

        results.sort(key=lambda x: x.correlation_strength, reverse=True)
        return results

    def get_incident_trend(
        self, repo_path: str, file_path: str
    ) -> dict[str, Any]:
        """Get incident trend for a specific file."""
        incidents = self.store.get_incidents_for_file(repo_path, file_path)
        if not incidents:
            return {
                "file_path": file_path,
                "total_incidents": 0,
                "trend": "none",
                "recent_incidents": [],
            }

        # Sort by timestamp
        incidents.sort(key=lambda i: i["timestamp"])

        # Split into halves to detect trend
        mid = len(incidents) // 2
        first_half = incidents[:mid] if mid > 0 else []
        second_half = incidents[mid:]

        if len(first_half) == 0:
            trend = "insufficient_data"
        elif len(second_half) > len(first_half):
            trend = "worsening"
        elif len(second_half) < len(first_half):
            trend = "improving"
        else:
            trend = "stable"

        return {
            "file_path": file_path,
            "total_incidents": len(incidents),
            "trend": trend,
            "recent_incidents": incidents[-5:],
        }
