"""
Normalization and scaling transformations.
"""

import pandas as pd
import polars as pl
from sklearn.preprocessing import MinMaxScaler, StandardScaler


# Pandas implementations
def normalize_pandas(
    df: pd.DataFrame,
    column: str,
    method: str = "minmax",
    range_min: float = 0.0,
    range_max: float = 1.0,
) -> pd.DataFrame:
    """
    Normalize a numeric column.

    Args:
        method: 'minmax' or 'zscore'
        range_min: Min value for minmax scaling
        range_max: Max value for minmax scaling
    """
    df = df.copy()

    if method == "minmax":
        scaler = MinMaxScaler(feature_range=(range_min, range_max))
        df[column] = scaler.fit_transform(df[[column]])
    elif method == "zscore":
        df[column] = (df[column] - df[column].mean()) / df[column].std()
    else:
        raise ValueError(f"Unknown normalization method: {method}")

    return df


def standardize_pandas(df: pd.DataFrame, column: str) -> pd.DataFrame:
    """Standardize a numeric column (z-score normalization)."""
    df = df.copy()
    scaler = StandardScaler()
    df[column] = scaler.fit_transform(df[[column]])
    return df


# Polars implementations
def normalize_polars(
    df: pl.DataFrame,
    column: str,
    method: str = "minmax",
    range_min: float = 0.0,
    range_max: float = 1.0,
) -> pl.DataFrame:
    """Normalize a numeric column."""
    if method == "minmax":
        col_min = df[column].min()
        col_max = df[column].max()
        df = df.with_columns(
            (
                (pl.col(column) - col_min) / (col_max - col_min) * (range_max - range_min)
                + range_min
            ).alias(column)
        )
    elif method == "zscore":
        mean = df[column].mean()
        std = df[column].std()
        df = df.with_columns(((pl.col(column) - mean) / std).alias(column))
    else:
        raise ValueError(f"Unknown normalization method: {method}")

    return df


def standardize_polars(df: pl.DataFrame, column: str) -> pl.DataFrame:
    """Standardize a numeric column (z-score normalization)."""
    mean = df[column].mean()
    std = df[column].std()
    df = df.with_columns(((pl.col(column) - mean) / std).alias(column))
    return df
