use autark::mpera::op::{JoinKind, ReduceKind};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;

pub(crate) fn reduce_kind(kind: &str) -> PyResult<ReduceKind> {
    Ok(match kind {
        "sum" => ReduceKind::Sum,
        "product" => ReduceKind::Product,
        "mean" => ReduceKind::Mean,
        "count" | "len" => ReduceKind::Count,
        "stdev" | "std" => ReduceKind::Stdev,
        "min" => ReduceKind::Min,
        "max" => ReduceKind::Max,
        "last" => ReduceKind::Last,
        _ => {
            return Err(PyValueError::new_err(
                "reduce kind must be one of: sum, product, mean, count, stdev, min, max, last",
            ));
        }
    })
}

pub(crate) fn reduce_kind_with_x(kind: &str, x: Option<f64>) -> PyResult<ReduceKind> {
    if kind == "percentile" {
        let x = x.unwrap_or(0.5);
        if !(0.0..=1.0).contains(&x) {
            return Err(PyValueError::new_err(
                "reduce percentile x must be in range [0, 1]",
            ));
        }
        return Ok(ReduceKind::Percentile { x });
    }
    if x.is_some() {
        return Err(PyValueError::new_err(
            "reduce x is only supported for kind=percentile",
        ));
    }
    reduce_kind(kind)
}

pub(crate) fn join_kind(kind: &str) -> PyResult<JoinKind> {
    Ok(match kind {
        "inner" => JoinKind::Inner,
        "left_outer" => JoinKind::LeftOuter,
        "asof_backward" => JoinKind::AsOfBackward,
        "asof_forward" => JoinKind::AsOfForward,
        _ => {
            return Err(PyValueError::new_err(
                "join kind must be one of: inner, left_outer, asof_backward, asof_forward",
            ));
        }
    })
}
