"""Unicode strikethrough utilities."""

# COMBINING LONG STROKE OVERLAY (U+0336)
STRIKETHROUGH_CHAR = '\u0336'


def apply_strikethrough(text: str, preserve_newlines: bool = True) -> str:
    """
    Add strikethrough to text using Unicode combining characters.

    Args:
        text: Text to strike through
        preserve_newlines: If True, don't strikethrough newlines

    Returns:
        Text with strikethrough combining characters

    Example:
        >>> apply_strikethrough("hello")
        'h̶e̶l̶l̶o̶'
    """
    if not text:
        return text

    result = []
    for char in text:
        result.append(char)
        # Skip newlines if preserving them
        if preserve_newlines and char in ('\n', '\r'):
            continue
        # Don't double-strike
        if len(result) >= 2 and result[-2] == STRIKETHROUGH_CHAR:
            continue
        result.append(STRIKETHROUGH_CHAR)

    return ''.join(result)


def is_struck_through(text: str, pos: int) -> bool:
    """
    Check if character at position has strikethrough.

    Args:
        text: Text to check
        pos: Position of character to check

    Returns:
        True if character at pos is struck through
    """
    if pos < 0 or pos >= len(text):
        return False

    # Check if next character is strikethrough combining char
    if pos + 1 < len(text):
        return text[pos + 1] == STRIKETHROUGH_CHAR

    return False


def strike_character_at(text: str, pos: int) -> str:
    """
    Strike through a single character at position.

    Args:
        text: Original text
        pos: Position of character to strike

    Returns:
        Text with character at pos struck through

    Example:
        >>> strike_character_at("hello", 0)
        'h̶ello'
    """
    if pos < 0 or pos >= len(text):
        return text

    # Don't strike newlines
    if text[pos] in ('\n', '\r'):
        return text

    # Check if already struck
    if is_struck_through(text, pos):
        return text

    # Insert strikethrough after character
    before = text[:pos + 1]
    after = text[pos + 1:]
    return before + STRIKETHROUGH_CHAR + after
