"""Shared validation helpers for the ACMS domain models."""

from __future__ import annotations

import unicodedata

__all__ = ["validate_non_blank"]

# Zero-width and invisible format characters that ``str.strip()``
# does not remove (Unicode category Cf).
_INVISIBLE_CODEPOINTS = frozenset(
    "\u200b"  # ZERO WIDTH SPACE
    "\u200c"  # ZERO WIDTH NON-JOINER
    "\u200d"  # ZERO WIDTH JOINER
    "\ufeff"  # BYTE ORDER MARK / ZERO WIDTH NO-BREAK SPACE
)


def _is_visible(ch: str) -> bool:
    """Return ``True`` if *ch* is a visible (non-whitespace, non-format) character."""
    if ch in _INVISIBLE_CODEPOINTS:
        return False
    cat = unicodedata.category(ch)
    # Zs = space separator, Cf = format character, Cc = control
    return cat not in {"Zs", "Cf", "Cc"}


def validate_non_blank(value: str, field_name: str) -> str:
    """Raise ``ValueError`` if *value* is empty, whitespace-only, or invisible.

    Also rejects strings composed entirely of zero-width Unicode
    characters (U+200B, U+200C, U+200D, U+FEFF) that pass
    ``str.strip()`` / ``str.isspace()`` checks.

    Returns *value* unchanged so the function can be used as a
    pass-through in Pydantic ``@field_validator`` methods.
    """
    if not value or not any(_is_visible(ch) for ch in value):
        msg = f"{field_name} must be a non-empty, non-whitespace string"
        raise ValueError(msg)
    return value
