"""detect_distribution_type — Classify the distribution shape of a sample."""

import math
import numpy as np


def detect_distribution_type(values: list[float]) -> dict:
    """Classify the distribution shape of a numeric sample.

    Uses skewness, excess kurtosis, tail ratio (p99/p50), and log-skewness
    to assign one of: normal-ish, lognormal-ish, heavy-tail, right-skewed,
    left-skewed, other, or too_few_samples (n < 30).

    Args:
        values: List of numeric values.

    Returns:
        Dict with keys:
          "type" (str): distribution label.
          "stats" (dict): {"n", "skew", "kurtosis", "tail_ratio", "log_skew"}.
    """
    n = len(values)
    if n < 30:
        return {"type": "too_few_samples", "stats": {"n": n}}

    arr = np.array(values, dtype=float)

    mean = float(np.mean(arr))
    std = float(np.std(arr, ddof=1))

    # Skewness
    if std == 0:
        skew = 0.0
    else:
        skew = float(np.mean(((arr - mean) / std) ** 3))

    # Excess kurtosis
    if std == 0:
        kurt = 0.0
    else:
        kurt = float(np.mean(((arr - mean) / std) ** 4)) - 3.0

    # Tail ratio: p99 / p50 (only meaningful when median != 0)
    p50 = float(np.percentile(arr, 50))
    p99 = float(np.percentile(arr, 99))
    tail_ratio = (p99 / p50) if p50 != 0 else math.nan

    # Log-skewness on positive values
    positives = arr[arr > 0]
    if len(positives) >= 30:
        log_arr = np.log(positives)
        log_mean = float(np.mean(log_arr))
        log_std = float(np.std(log_arr, ddof=1))
        if log_std == 0:
            log_skew = 0.0
        else:
            log_skew = float(np.mean(((log_arr - log_mean) / log_std) ** 3))
    else:
        log_skew = math.nan

    stats = {
        "n": n,
        "skew": skew,
        "kurtosis": kurt,
        "tail_ratio": tail_ratio,
        "log_skew": log_skew,
    }

    # Classification logic
    if kurt > 3.0:
        dist_type = "heavy-tail"
    elif abs(skew) <= 0.5 and abs(kurt) <= 1.0:
        dist_type = "normal-ish"
    elif (
        skew > 0.5
        and not math.isnan(log_skew)
        and abs(log_skew) <= 0.5
        and not math.isnan(tail_ratio)
        and tail_ratio > 2.0
    ):
        dist_type = "lognormal-ish"
    elif skew > 0.5:
        dist_type = "right-skewed"
    elif skew < -0.5:
        dist_type = "left-skewed"
    else:
        dist_type = "other"

    return {"type": dist_type, "stats": stats}
