"""Tests for QuranValidator."""

from quran_validator import QuranValidator, create_validator


class TestValidate:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_validate_bismillah_uthmani(self):
        result = self.validator.validate("بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ")
        assert result.is_valid is True
        assert result.match_type in ("exact", "normalized")
        assert result.reference == "1:1"

    def test_validate_exact_match_from_data(self):
        verse = self.validator.get_verse(1, 1)
        assert verse is not None
        result = self.validator.validate(verse.text)
        assert result.is_valid is True
        assert result.match_type == "exact"
        assert result.reference == "1:1"

    def test_validate_ayat_al_kursi(self):
        ayat_kursi = (
            "ٱللَّهُ لَآ إِلَٰهَ إِلَّا هُوَ ٱلْحَىُّ ٱلْقَيُّومُ ۚ "
            "لَا تَأْخُذُهُۥ سِنَةٌۭ وَلَا نَوْمٌۭ ۚ لَّهُۥ مَا فِى ٱلسَّمَٰوَٰتِ "
            "وَمَا فِى ٱلْأَرْضِ ۗ مَن ذَا ٱلَّذِى يَشْفَعُ عِندَهُۥٓ إِلَّا بِإِذْنِهِۦ ۚ "
            "يَعْلَمُ مَا بَيْنَ أَيْدِيهِمْ وَمَا خَلْفَهُمْ ۖ وَلَا يُحِيطُونَ بِشَىْءٍۢ "
            "مِّنْ عِلْمِهِۦٓ إِلَّا بِمَا شَآءَ ۚ وَسِعَ كُرْسِيُّهُ ٱلسَّمَٰوَٰتِ وَٱلْأَرْضَ ۖ "
            "وَلَا يَـُٔودُهُۥ حِفْظُهُمَا ۚ وَهُوَ ٱلْعَلِىُّ ٱلْعَظِيمُ"
        )
        result = self.validator.validate(ayat_kursi)
        assert result.is_valid is True
        assert result.reference == "2:255"

    def test_non_quran_arabic(self):
        result = self.validator.validate("مرحبا كيف حالك اليوم")
        assert result.is_valid is False
        assert result.match_type == "none"

    def test_reject_partial_verses(self):
        result = self.validator.validate("بسم الله")
        assert result.is_valid is False
        assert result.match_type == "none"

    def test_empty_string(self):
        result = self.validator.validate("")
        assert result.is_valid is False
        assert result.match_type == "none"

    def test_non_arabic_text(self):
        result = self.validator.validate("Hello world")
        assert result.is_valid is False
        assert result.match_type == "none"

    def test_al_ikhlas_112_1(self):
        result = self.validator.validate("قُلْ هُوَ ٱللَّهُ أَحَدٌ")
        assert result.is_valid is True
        assert result.reference == "112:1"

    def test_al_falaq_113_1(self):
        result = self.validator.validate("قُلْ أَعُوذُ بِرَبِّ ٱلْفَلَقِ")
        assert result.is_valid is True
        assert result.reference == "113:1"

    def test_an_nas_114_1(self):
        result = self.validator.validate("قُلْ أَعُوذُ بِرَبِّ ٱلنَّاسِ")
        assert result.is_valid is True
        assert result.reference == "114:1"

    def test_common_alef_instead_of_alef_wasla(self):
        result = self.validator.validate("قل هو الله أحد")
        assert result.is_valid is True
        assert result.reference == "112:1"


class TestDetectAndValidate:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_detect_in_mixed_text(self):
        text = 'The verse بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ means "In the name of Allah"'
        result = self.validator.detect_and_validate(text)
        assert result.detected is True
        assert len(result.segments) > 0
        assert result.segments[0].validation is not None
        assert result.segments[0].validation.is_valid is True

    def test_no_arabic_content(self):
        result = self.validator.detect_and_validate("This is just English text with no Arabic")
        assert result.detected is False
        assert len(result.segments) == 0

    def test_multiple_segments(self):
        text = "First verse: بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ and another: قُلْ هُوَ ٱللَّهُ أَحَدٌ"
        result = self.validator.detect_and_validate(text)
        assert result.detected is True
        assert len(result.segments) == 2

    def test_skip_short_text(self):
        text = "Just الله here"
        result = self.validator.detect_and_validate(text)
        # "الله" is shorter than default min_detection_length (10)
        assert all(len(s.text) >= 10 for s in result.segments)


class TestGetVerse:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_get_by_surah_ayah(self):
        verse = self.validator.get_verse(1, 1)
        assert verse is not None
        assert verse.surah == 1
        assert verse.ayah == 1
        assert "بِسْمِ" in verse.text

    def test_invalid_reference(self):
        verse = self.validator.get_verse(115, 1)
        assert verse is None


class TestGetSurah:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_get_surah(self):
        surah = self.validator.get_surah(1)
        assert surah is not None
        assert "الفاتحة" in surah.name
        assert surah.english_name == "Al-Fatiha"
        assert surah.verses_count == 7

    def test_invalid_surah(self):
        surah = self.validator.get_surah(115)
        assert surah is None

    def test_al_baqara_count(self):
        surah = self.validator.get_surah(2)
        assert surah is not None
        assert surah.verses_count == 286


class TestSearch:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_search_verses(self):
        results = self.validator.search("الله الرحمان")
        assert len(results) > 0
        assert results[0]["similarity"] > 0.3

    def test_limit_results(self):
        results = self.validator.search("الله", 5)
        assert len(results) <= 5

    def test_empty_query(self):
        assert self.validator.search("") == []

    def test_whitespace_query(self):
        assert self.validator.search("   ") == []


class TestCreateValidator:
    def test_create_with_custom_options(self):
        from quran_validator.types import ValidatorOptions
        v = create_validator(ValidatorOptions(max_suggestions=5))
        assert isinstance(v, QuranValidator)


class TestDiffHighlighting:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_normalized_diff_for_no_match(self):
        result = self.validator.validate("بسم الله الرحمن")
        assert result.is_valid is False
        assert result.normalized_input is not None
        assert result.normalized_input == "بسم الله الرحمن"

    def test_diff_against_reference(self):
        result = self.validator.validate_against("بسم الله", "1:1")
        assert result.is_valid is False
        assert result.normalized_input is not None
        assert result.expected_normalized is not None
        assert result.expected_normalized == "بسم الله الرحمان الرحيم"

    def test_mismatch_positions(self):
        result = self.validator.validate_against("بسم الله الكريم الرحيم", "1:1")
        assert result.is_valid is False
        assert result.mismatch_index is not None
        assert result.mismatch_index > 0


class TestAnalyzeFabrication:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_real_quranic_sequence(self):
        result = self.validator.analyze_fabrication("بسم الله الرحمان الرحيم")
        assert len(result.words) == 4
        assert all(not w.is_fabricated for w in result.words)
        assert result.stats.fabricated_words == 0
        assert result.stats.fabricated_ratio == 0

    def test_individual_valid_words(self):
        result = self.validator.analyze_fabrication("الله السماء الأرض")
        assert len(result.words) == 3
        assert all(not w.is_fabricated for w in result.words)

    def test_fabricated_words(self):
        result = self.validator.analyze_fabrication("بسم الله الفلان")
        assert len(result.words) == 3
        assert result.words[0].is_fabricated is False
        assert result.words[1].is_fabricated is False
        assert result.words[2].is_fabricated is True
        assert result.stats.fabricated_words == 1

    def test_empty_input(self):
        result = self.validator.analyze_fabrication("")
        assert len(result.words) == 0
        assert result.stats.total_words == 0
        assert result.stats.fabricated_words == 0
        assert result.stats.fabricated_ratio == 0

    def test_completely_fabricated(self):
        result = self.validator.analyze_fabrication("الفلان البلان الكلان")
        assert len(result.words) == 3
        assert all(w.is_fabricated for w in result.words)
        assert result.stats.fabricated_words == 3
        assert result.stats.fabricated_ratio == 1

    def test_normalize_before_analyzing(self):
        result = self.validator.analyze_fabrication("بِسْمِ اللَّهِ")
        assert len(result.words) == 2
        assert all(not w.is_fabricated for w in result.words)

    def test_normalized_input_in_result(self):
        result = self.validator.analyze_fabrication("بِسْمِ اللَّهِ")
        assert result.normalized_input == "بسم الله"

    def test_contiguous_matches(self):
        result = self.validator.analyze_fabrication("قل هو الله احد")
        assert len(result.words) == 4
        assert all(not w.is_fabricated for w in result.words)

    def test_alef_superscript_alef_not_fabricated(self):
        result = self.validator.analyze_fabrication("وَالْمَسَاٰكِينِ")
        assert len(result.words) == 1
        assert result.words[0].is_fabricated is False

    def test_full_fragment_with_alef_superscript(self):
        result = self.validator.analyze_fabrication("إِنَّمَا الصَّدَقَاتُ لِلْفُقَرَاءِ وَالْمَسَاٰكِينِ")
        fabricated = [w for w in result.words if w.is_fabricated]
        assert len(fabricated) == 0


class TestUthmaniSadSinVariants:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_validate_2_247_sad_variant(self):
        verse = self.validator.get_verse(2, 247)
        assert verse is not None
        with_sad = verse.text.replace("بَسْطَةً", "بَصْطَةً")
        result = self.validator.validate(with_sad)
        assert result.is_valid is True
        assert result.reference == "2:247"

    def test_validate_7_69_sin_variant(self):
        verse = self.validator.get_verse(7, 69)
        assert verse is not None
        with_sin = verse.text.replace("بَصْۜطَةً", "بَسْطَةً")
        result = self.validator.validate(with_sin)
        assert result.is_valid is True
        assert result.reference == "7:69"

    def test_validate_2_245_sin_variant(self):
        verse = self.validator.get_verse(2, 245)
        assert verse is not None
        with_sin = verse.text.replace("وَيَبْصُۜطُ", "وَيَبْسُطُ")
        result = self.validator.validate(with_sin)
        assert result.is_valid is True
        assert result.reference == "2:245"

    def test_validate_52_37_sin_variant(self):
        verse = self.validator.get_verse(52, 37)
        assert verse is not None
        with_sin = verse.text.replace("ٱلْمُصَۣيْطِرُونَ", "ٱلْمُسَيْطِرُونَ")
        result = self.validator.validate(with_sin)
        assert result.is_valid is True
        assert result.reference == "52:37"

    def test_validate_88_22_sin_variant(self):
        verse = self.validator.get_verse(88, 22)
        assert verse is not None
        with_sin = verse.text.replace("بِمُصَيْطِرٍ", "بِمُسَيْطِرٍ")
        result = self.validator.validate(with_sin)
        assert result.is_valid is True
        assert result.reference == "88:22"

    def test_fabrication_sad_variant(self):
        result = self.validator.analyze_fabrication("بَصْطَةً")
        assert result.words[0].is_fabricated is False

    def test_fabrication_sin_variant(self):
        result = self.validator.analyze_fabrication("يَبْسُطُ")
        assert result.words[0].is_fabricated is False


class TestUthmaniSpacingVariants:
    def setup_method(self):
        self.validator = QuranValidator()

    def test_ya_adam_with_space_2_33(self):
        verse = self.validator.get_verse(2, 33)
        assert verse is not None
        common = verse.text.replace("يَـٰٓـَٔادَمُ", "يَا آدَمُ")
        result = self.validator.validate(common)
        assert result.is_valid is True
        assert result.reference == "2:33"

    def test_ya_adam_with_hamza_2_33(self):
        verse = self.validator.get_verse(2, 33)
        assert verse is not None
        common = verse.text.replace("يَـٰٓـَٔادَمُ", "يَا ءَادَمُ")
        result = self.validator.validate(common)
        assert result.is_valid is True
        assert result.reference == "2:33"

    def test_ya_ayyuha_with_space_2_21(self):
        verse = self.validator.get_verse(2, 21)
        assert verse is not None
        common = verse.text.replace("يَـٰٓأَيُّهَا", "يَا أَيُّهَا")
        result = self.validator.validate(common)
        assert result.is_valid is True
        assert result.reference == "2:21"

    def test_ya_ayyuha_without_superscript_alef(self):
        verse = self.validator.get_verse(2, 21)
        assert verse is not None
        variant = verse.text.replace("يَـٰٓأَيُّهَا", "يَـأَيُّهَا")
        result = self.validator.validate(variant)
        assert result.is_valid is True
        assert result.reference == "2:21"
