"""Tests for gherbal.preprocessing module."""

import pytest
from gherbal.preprocessing import (
    preprocess_text,
    clean_script,
    unscript,
    create_clean_script_function,
)


class TestPreprocessText:
    """Tests for preprocess_text function."""

    def test_basic_text(self):
        result = preprocess_text("Hello World")
        assert isinstance(result, str)
        assert result == result.lower()

    def test_empty_string(self):
        assert preprocess_text("") == ""

    def test_none_returns_empty(self):
        assert preprocess_text(None) == ""

    def test_non_string_returns_empty(self):
        assert preprocess_text(123) == ""
        assert preprocess_text([]) == ""

    def test_removes_urls(self):
        result = preprocess_text("Check https://example.com out")
        assert "https" not in result
        assert "example" not in result

    def test_removes_mentions(self):
        result = preprocess_text("Hello @user123 how are you")
        assert "@user123" not in result
        assert "@" not in result

    def test_removes_hashtags(self):
        result = preprocess_text("This is #awesome content")
        assert "#awesome" not in result

    def test_lowercase(self):
        result = preprocess_text("HELLO WORLD")
        assert result == result.lower()

    def test_arabic_text(self):
        result = preprocess_text("مرحبا بالعالم")
        assert len(result) > 0

    def test_mixed_script_text(self):
        result = preprocess_text("Hello مرحبا World")
        assert isinstance(result, str)

    def test_whitespace_normalization(self):
        result = preprocess_text("hello    world   test")
        assert "  " not in result

    def test_emoji_removal(self):
        result = preprocess_text("Hello 🌍 World 🎉")
        assert "🌍" not in result
        assert "🎉" not in result

    def test_numbers_only_returns_empty(self):
        # The unscript clean_text collapses to empty for numbers-only
        result = preprocess_text("12345")
        # May be empty or the number — depends on unscript behavior
        assert isinstance(result, str)

    def test_newlines_handled(self):
        result = preprocess_text("hello\nworld\ntest")
        assert "\n" not in result

    def test_unicode_normalization(self):
        # NFD vs NFC chars
        result = preprocess_text("café résumé")
        assert isinstance(result, str)
        assert len(result) > 0


class TestCleanScript:
    """Tests for clean_script function."""

    def test_latin_script(self):
        result = clean_script("Latn", "Hello World مرحبا")
        # Should keep Latin, remove Arabic
        assert "مرحبا" not in result
        # Latin letters should remain (possibly)
        assert isinstance(result, str)

    def test_arabic_script(self):
        result = clean_script("Arab", "Hello مرحبا بالعالم World")
        assert isinstance(result, str)
        # Should remove Latin letters
        assert "Hello" not in result
        assert "World" not in result

    def test_empty_text(self):
        assert clean_script("Latn", "") == ""
        assert clean_script("Latn", None) is None

    def test_config_with_numbers(self):
        result = clean_script("Latn", "Hello 123 World", config={"numbers": True})
        assert isinstance(result, str)

    def test_config_without_numbers(self):
        result = clean_script("Latn", "Hello 123 World", config={"numbers": False})
        assert isinstance(result, str)

    def test_config_with_spaces(self):
        result = clean_script("Latn", "Hello World", config={"spaces": True})
        assert " " in result or len(result) == 0

    def test_cyrillic_script(self):
        result = clean_script("Cyrl", "Hello Доброе утро World")
        assert isinstance(result, str)

    def test_devanagari_script(self):
        result = clean_script("Deva", "Hello नमस्ते World")
        assert isinstance(result, str)

    def test_hangul_script(self):
        result = clean_script("Hang", "Hello 안녕하세요 World")
        assert isinstance(result, str)


class TestUnscript:
    """Tests for unscript (combined clean_text + clean_script)."""

    def test_basic_latin(self):
        result = unscript("Latn", "Hello World! @user https://test.com")
        assert isinstance(result, str)
        assert "@" not in result
        assert "https" not in result

    def test_basic_arabic(self):
        result = unscript("Arab", "مرحبا @user بالعالم https://test.com #tag")
        assert isinstance(result, str)

    def test_empty_text(self):
        assert unscript("Latn", "") == ""

    def test_none_text(self):
        assert unscript("Latn", None) is None

    def test_lowercase_option(self):
        result = unscript("Latn", "HELLO WORLD", lowercase=True)
        if result:
            assert result == result.lower()

    def test_with_config(self):
        result = unscript("Latn", "Hello 123 World", config={"numbers": True})
        assert isinstance(result, str)


class TestCreateCleanScriptFunction:
    """Tests for the factory function create_clean_script_function."""

    def test_default_config(self):
        fn = create_clean_script_function()
        result = fn("Latn", "Hello World")
        assert isinstance(result, str)

    def test_custom_config(self):
        fn = create_clean_script_function({"spaces": True, "numbers": True})
        result = fn("Latn", "Hello 123 World")
        assert isinstance(result, str)

    def test_override_at_call_time(self):
        fn = create_clean_script_function({"numbers": False})
        result = fn("Latn", "Hello 123", config={"numbers": True})
        assert isinstance(result, str)

    def test_empty_text(self):
        fn = create_clean_script_function()
        assert fn("Latn", "") == ""
        assert fn("Latn", None) is None

    def test_multiple_calls_same_function(self):
        fn = create_clean_script_function()
        r1 = fn("Latn", "Hello World")
        r2 = fn("Arab", "مرحبا بالعالم")
        assert isinstance(r1, str)
        assert isinstance(r2, str)

    def test_all_options_disabled(self):
        fn = create_clean_script_function({
            "spaces": False,
            "numbers": False,
            "punctuation": False,
            "symbols": False,
        })
        result = fn("Latn", "Hello, World! 123")
        assert isinstance(result, str)

    def test_all_options_enabled(self):
        fn = create_clean_script_function({
            "spaces": True,
            "numbers": True,
            "punctuation": True,
            "symbols": True,
        })
        result = fn("Latn", "Hello, World! 123 $$$")
        assert isinstance(result, str)
