"""Analytics module - performance analysis and reporting.

This module provides analytics capabilities for cleave performance metrics,
including trend analysis, slowness detection, and regression monitoring.
"""

from __future__ import annotations

from cleave.core.performance import get_metrics


def generate_analytics() -> dict:
    """Generate comprehensive analytics from performance metrics.

    Returns:
        Dict containing analytics data including:
        - total_operations: Number of distinct operations tracked
        - total_executions: Total number of function calls
        - operations: List of operation details with stats
        - summary: Overall summary statistics
    """
    metrics = get_metrics()

    if not metrics:
        return {
            "total_operations": 0,
            "total_executions": 0,
            "operations": [],
            "summary": {
                "total_time": 0.0,
                "avg_time": 0.0,
            },
        }

    operations = []
    total_executions = 0
    total_time = 0.0

    for name, data in metrics.items():
        count = data.get("count", 0)
        avg_time = data.get("avg_time", 0.0)
        total_op_time = data.get("total_time", 0.0)

        total_executions += count
        total_time += total_op_time

        operations.append({
            "name": name,
            "count": count,
            "avg_time": avg_time,
            "total_time": total_op_time,
            "min_time": data.get("min_time"),
            "max_time": data.get("max_time"),
            "last_time": data.get("last_time"),
            "peak_memory_mb": data.get("peak_memory_mb"),
            "avg_memory_mb": data.get("avg_memory_mb"),
        })

    # Sort by total time (slowest first)
    operations.sort(key=lambda x: x["total_time"], reverse=True)

    return {
        "total_operations": len(operations),
        "total_executions": total_executions,
        "operations": operations,
        "summary": {
            "total_time": total_time,
            "avg_time": total_time / total_executions if total_executions > 0 else 0.0,
        },
    }


def get_slow_operations(threshold_seconds: float = 1.0) -> list[dict]:
    """Identify slow operations that exceed a time threshold.

    Args:
        threshold_seconds: Minimum average time to be considered slow

    Returns:
        List of slow operations sorted by avg_time (slowest first)
    """
    metrics = get_metrics()

    slow_ops = []
    for name, data in metrics.items():
        avg_time = data.get("avg_time", 0.0)
        if avg_time >= threshold_seconds:
            slow_ops.append({
                "name": name,
                "avg_time": avg_time,
                "max_time": data.get("max_time", 0.0),
                "count": data.get("count", 0),
            })

    # Sort by average time (slowest first)
    slow_ops.sort(key=lambda x: x["avg_time"], reverse=True)

    return slow_ops


def get_memory_hotspots(threshold_mb: float = 100.0) -> list[dict]:
    """Identify memory-intensive operations.

    Args:
        threshold_mb: Minimum peak memory to be considered a hotspot

    Returns:
        List of memory hotspots sorted by peak_memory_mb (highest first)
    """
    metrics = get_metrics()

    hotspots = []
    for name, data in metrics.items():
        peak_memory = data.get("peak_memory_mb", 0.0)
        if peak_memory >= threshold_mb:
            hotspots.append({
                "name": name,
                "peak_memory_mb": peak_memory,
                "avg_memory_mb": data.get("avg_memory_mb", 0.0),
                "count": data.get("count", 0),
            })

    # Sort by peak memory (highest first)
    hotspots.sort(key=lambda x: x["peak_memory_mb"], reverse=True)

    return hotspots


def get_trends() -> dict:
    """Analyze trends in performance metrics.

    Returns:
        Dict containing trend data for operations
    """
    metrics = get_metrics()

    trends = {"operations": []}

    for name, data in metrics.items():
        count = data.get("count", 0)

        # Only generate trends for operations with multiple executions
        if count < 2:
            continue

        avg_time = data.get("avg_time", 0.0)
        last_time = data.get("last_time", 0.0)

        # Calculate trend direction
        if last_time > avg_time * 1.2:
            trend = "slower"
        elif last_time < avg_time * 0.8:
            trend = "faster"
        else:
            trend = "stable"

        trends["operations"].append({
            "name": name,
            "trend": trend,
            "avg_time": avg_time,
            "last_time": last_time,
            "count": count,
        })

    return trends


def detect_regressions(threshold_factor: float = 2.0) -> list[dict]:
    """Detect performance regressions.

    A regression is detected when the last execution time is significantly
    slower than the average (by threshold_factor or more).

    Args:
        threshold_factor: How many times slower to trigger regression alert

    Returns:
        List of operations with detected regressions
    """
    metrics = get_metrics()

    regressions = []

    for name, data in metrics.items():
        avg_time = data.get("avg_time", 0.0)
        last_time = data.get("last_time", 0.0)
        count = data.get("count", 0)

        # Need at least 2 executions to detect regression
        if count < 2:
            continue

        if last_time > avg_time * threshold_factor:
            regressions.append({
                "operation": name,
                "avg_time": avg_time,
                "last_time": last_time,
                "regression_factor": last_time / avg_time if avg_time > 0 else 0,
                "count": count,
            })

    # Sort by regression factor (worst first)
    regressions.sort(key=lambda x: x["regression_factor"], reverse=True)

    return regressions
