"""Outlier masking — mark statistical outlier pixels."""

from __future__ import annotations

import numpy as np

from backend.node_registry import register_node
from backend.data_types import DataField
from backend.nodes.helpers import bool_to_mask


@register_node(display_name="Outlier Mask")
class OutlierMask:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "field": ("DATA_FIELD",),
                "sigma_threshold": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10.0, "step": 0.1}),
                "mode": (["both", "high", "low"], {"default": "both"}),
            }
        }

    OUTPUTS = (
        ('IMAGE', 'mask'),
    )
    FUNCTION = "process"

    DESCRIPTION = (
        "Create a mask marking pixels that deviate more than N standard "
        "deviations from the mean. Mode selects whether to flag high outliers, "
        "low outliers, or both. Quick way to identify noise spikes and defects. "
    )

    def process(self, field: DataField, sigma_threshold: float, mode: str) -> tuple:
        data = np.asarray(field.data, dtype=np.float64)
        mean = data.mean()
        std = data.std()

        if std < 1e-30:
            return (bool_to_mask(np.zeros(data.shape, dtype=bool)),)

        z = (data - mean) / std

        if mode == "both":
            outliers = np.abs(z) > sigma_threshold
        elif mode == "high":
            outliers = z > sigma_threshold
        elif mode == "low":
            outliers = z < -sigma_threshold
        else:
            raise ValueError(f"Unknown mode: {mode!r}")

        return (bool_to_mask(outliers),)
