from typing import Literal, Optional

from ....types.validation.threshold import Threshold, CheckThreshold
from ....exceptions import InvalidThresholdError


type ThresholdType = Threshold | dict[str, CheckThreshold] | None


def parse_to_threshold(
    thresholds: ThresholdType = None,
    debug: Optional[CheckThreshold] = None,
    warning: Optional[CheckThreshold] = None,
    error: Optional[CheckThreshold] = None,
    reject: Optional[CheckThreshold] = None,
    remove_row_on_fail: bool = False,
) -> Threshold | None:
    # If we are excluding the row, we want to reject when all rows fail
    default_reject: Literal["all"] | None = (
        "all" if remove_row_on_fail is True else None
    )

    # self.thresholds takes precedence over self.warning, self.error, self.reject
    if thresholds is None:
        if (
            debug is not None
            or warning is not None
            or error is not None
            or reject is not None
        ):
            return Threshold(
                debug=debug,
                warning=warning,
                error=error,
                reject=reject or default_reject,
            )

        if remove_row_on_fail is True:
            return Threshold(warning=True, reject=default_reject)
        else:
            return None

    elif isinstance(thresholds, Threshold):
        return Threshold(
            debug=thresholds.debug,
            warning=thresholds.warning,
            error=thresholds.error,
            reject=thresholds.reject or default_reject,
        )
    elif isinstance(thresholds, dict):
        return Threshold(
            debug=thresholds.get("debug", None),
            warning=thresholds.get("warning", None),
            error=thresholds.get("error", None),
            reject=thresholds.get("reject", default_reject),
        )
    else:
        raise InvalidThresholdError(f"Invalid type for thresholds: {type(thresholds)}")
