"""
Linear Regression Playground — interactive parameter exploration.
"""

import numpy as np

META = {
    "title": "Linear Regression",
    "icon": "📈",
    "description": (
        "Explore how linear regression fits a line through noisy data. "
        "Adjust the noise level, polynomial degree, and number of data points "
        "to see how the model adapts."
    ),
}

PARAMS = [
    {
        "name": "n_points",
        "label": "Data Points",
        "type": "slider",
        "min": 10,
        "max": 200,
        "step": 10,
        "default": 50,
    },
    {
        "name": "noise",
        "label": "Noise Level",
        "type": "slider",
        "min": 0.0,
        "max": 10.0,
        "step": 0.5,
        "default": 3.0,
    },
    {
        "name": "degree",
        "label": "Polynomial Degree",
        "type": "slider",
        "min": 1,
        "max": 10,
        "step": 1,
        "default": 1,
    },
]


def compute(params: dict) -> dict:
    """Compute scatter + fitted curve from parameters."""
    n = int(params.get("n_points", 50))
    noise = float(params.get("noise", 3.0))
    degree = int(params.get("degree", 1))

    np.random.seed(42)
    X = np.linspace(0, 10, n)
    y_true = 2.5 * X + 1
    y = y_true + np.random.normal(0, noise, size=n)

    # Fit polynomial
    coeffs = np.polyfit(X, y, degree)
    X_smooth = np.linspace(0, 10, 200)
    y_fit = np.polyval(coeffs, X_smooth)

    # Compute R² on training data
    y_pred_train = np.polyval(coeffs, X)
    ss_res = np.sum((y - y_pred_train) ** 2)
    ss_tot = np.sum((y - np.mean(y)) ** 2)
    r2 = 1 - ss_res / ss_tot if ss_tot > 0 else 0

    data = [
        {
            "x": X.tolist(),
            "y": y.tolist(),
            "mode": "markers",
            "type": "scatter",
            "name": "Data Points",
            "marker": {
                "size": 8,
                "color": "#6C63FF",
                "opacity": 0.8,
                "line": {"width": 1, "color": "#fff"},
            },
        },
        {
            "x": X_smooth.tolist(),
            "y": y_fit.tolist(),
            "mode": "lines",
            "type": "scatter",
            "name": f"Fit (degree={degree}, R²={r2:.3f})",
            "line": {"color": "#FF6584", "width": 3},
        },
    ]

    layout = {
        "template": "plotly_dark",
        "paper_bgcolor": "rgba(0,0,0,0)",
        "plot_bgcolor": "rgba(0,0,0,0)",
        "title": {"text": f"Linear Regression — Degree {degree}", "font": {"size": 20}},
        "xaxis": {"title": "X", "gridcolor": "rgba(255,255,255,0.08)"},
        "yaxis": {"title": "y", "gridcolor": "rgba(255,255,255,0.08)"},
        "legend": {"x": 0.02, "y": 0.98},
        "margin": {"l": 60, "r": 30, "t": 60, "b": 50},
    }

    return {"data": data, "layout": layout}
