"""Tag path validation utilities for CLI.

Validates tag paths against server constraints before submission to provide
immediate feedback in the TUI instead of server-side errors.

This mirrors the server-side validation in domain/tag_validation.py.
"""

import re

# Matches the database constraint: ^[a-z0-9_.]+$
TAG_PATH_PATTERN = re.compile(r"^[a-z0-9_.]+$")

# Maximum hierarchy depth (matches database constraint: nlevel(tag_path) <= 10)
MAX_TAG_DEPTH = 10


def validate_tag_path(tag_path: str) -> tuple[bool, str | None]:
    """
    Validate a tag path against database constraints.

    Returns a tuple of (is_valid, error_message).
    If valid, error_message is None.

    Constraints:
    - Only lowercase letters (a-z), numbers (0-9), underscores (_), and dots (.)
    - Dots are level separators (e.g., 'marketing.email.newsletter')
    - Maximum 10 levels deep
    - Cannot be empty
    - Cannot start or end with a dot
    - Cannot have consecutive dots

    Args:
        tag_path: The tag path to validate (e.g., 'marketing.email')

    Returns:
        Tuple of (is_valid, error_message or None)
    """
    if not tag_path:
        return False, "Tag path cannot be empty"

    # Check for uppercase letters (common mistake)
    if tag_path != tag_path.lower():
        suggestion = tag_path.lower()
        return False, f"Must be lowercase. Try: {suggestion}"

    # Check for hyphens (common mistake - suggest underscore)
    if "-" in tag_path:
        suggestion = tag_path.replace("-", "_")
        return False, f"Use underscores, not hyphens. Try: {suggestion}"

    # Check for spaces
    if " " in tag_path:
        suggestion = tag_path.replace(" ", "_")
        return False, f"No spaces allowed. Try: {suggestion}"

    # Check for consecutive dots
    if ".." in tag_path:
        return False, "Cannot contain consecutive dots (..)"

    # Check for leading/trailing dots
    if tag_path.startswith(".") or tag_path.endswith("."):
        return False, "Cannot start or end with a dot"

    # Check general format (must match ^[a-z0-9_.]+$)
    if not TAG_PATH_PATTERN.match(tag_path):
        return False, "Only lowercase letters, numbers, underscores, and dots allowed"

    # Check depth (count dots + 1 = levels)
    depth = tag_path.count(".") + 1
    if depth > MAX_TAG_DEPTH:
        return False, f"Too deep ({depth} levels). Maximum is {MAX_TAG_DEPTH}"

    return True, None
