"""
Shared helpers for computing field fill rates and sanitized values.

These functions normalise string-like values so metrics such as fill rate
agree between Salesforce-API sourced data and CSV uploads (where blank strings
or textual NULL markers should be treated as missing).
"""

from __future__ import annotations

from typing import Any, Optional, Set, Tuple

import pandas as pd

_NULL_STRINGS: Set[str] = {"", "null", "none", "n/a", "na", "nan"}


def normalize_scalar(value: Any) -> Optional[str]:
    """
    Return a trimmed string for non-null values, otherwise None.

    The normalisation treats textual NULL / empty markers as missing so that
    downstream fill-rate calculations behave consistently across data sources.
    """
    if value is None:
        return None
    if isinstance(value, float) and pd.isna(value):
        return None

    text = str(value).strip()
    if not text:
        return None
    if text.lower() in _NULL_STRINGS:
        return None
    return text


def normalise_series(
    series: pd.Series,
) -> Tuple[pd.Series, pd.Series]:
    """
    Return (mask, cleaned_series) where mask marks populated rows and
    cleaned_series contains trimmed string representations for populated rows.
    """
    if series.empty:
        empty_mask = pd.Series([False] * 0, dtype=bool)
        empty_values = pd.Series([], dtype="object")
        return empty_mask, empty_values

    str_series = series.astype(str)
    cleaned = str_series.str.strip()
    lower = cleaned.str.lower()

    mask = series.notna()
    mask &= cleaned != ""
    mask &= ~lower.isin(_NULL_STRINGS)

    cleaned = cleaned.where(mask, None)
    return mask, cleaned
