"""Smoke tests for the experimental StreamingQuranMatcher."""

from ijaza import QuranValidator
from ijaza.stream_matcher import (
    StreamingQuranMatcher,
    StreamingQuranMatcherOptions,
)
from ijaza.types import ValidatorOptions


class TestStreamingQuranMatcher:
    def test_reset_clears_state(self):
        matcher = StreamingQuranMatcher()
        matcher.process_chunk("بعض النص ثم يا ايها الذين امنوا")
        matcher.reset()
        assert matcher._buffer_words == []
        assert matcher._buffer_norm_words == []
        assert matcher._active == {}
        assert matcher._buffer_start_token == 0

    def test_detects_verse_across_chunks(self):
        matcher = StreamingQuranMatcher(
            StreamingQuranMatcherOptions(
                min_confidence=0.8,
                asr_tolerant=True,
            )
        )
        r1 = matcher.process_chunk(
            "خليله أشهد أنّه بلغ الرسالة وأدى الأمانة ونصح للأمة"
        )
        r2 = matcher.process_chunk(
            "أما بعد يقول الله عز وجل: يا أيها الذين آمنوا "
            "اتقوا الله حق تقاته ولا تموتن إلا وأنتم مسلمون."
        )
        rf = matcher.flush()

        refs = [v.reference for v in (r1.complete_verses + r2.complete_verses + rf.complete_verses)]
        assert any(ref == "3:102" for ref in refs)

    def test_non_quran_chunk_returns_no_hits(self):
        matcher = StreamingQuranMatcher(
            StreamingQuranMatcherOptions(min_confidence=0.9)
        )
        r = matcher.process_chunk("هذا نص عادي لا يحتوي على ايات قرانية هنا")
        rf = matcher.flush()
        hits = r.complete_verses + rf.complete_verses
        assert hits == []

    def test_detects_partial_ayah_when_enabled(self):
        chunk = "ويقول كذلك اما الإنسان اذا ابتلاه ربه فأكرهه ونعمه فيقول ربي أكرمه"
        opts = StreamingQuranMatcherOptions(
            min_confidence=0.8,
            asr_tolerant=True,
            detect_partial_ayahs=True,
        )
        matcher = StreamingQuranMatcher(opts)

        r = matcher.process_chunk(chunk)
        rf = matcher.flush()
        partial_hits = r.partial_ayahs + rf.partial_ayahs

        refs = [h.reference for h in partial_hits if h.reference]
        assert "89:15" in refs

        hit_89_15 = next(h for h in partial_hits if h.reference == "89:15")
        assert hit_89_15.is_partial is True
        assert hit_89_15.partial_score >= opts.partial_min_score

    def test_partial_span_is_trimmed_to_ayah_fragment(self):
        chunk = (
            "والله يعلم وأنتم لا تعلمون. "
            "ويقول كذلك اما الإنسان اذا ابتلاه ربه فأكرهه ونعمه فيقول ربي أكرمه"
        )
        opts = StreamingQuranMatcherOptions(
            min_confidence=0.8,
            asr_tolerant=True,
            detect_partial_ayahs=True,
        )
        matcher = StreamingQuranMatcher(opts)

        r = matcher.process_chunk(chunk)
        refs = [h.reference for h in r.partial_ayahs if h.reference]
        assert "89:15" in refs

        hit = next(h for h in r.partial_ayahs if h.reference == "89:15")
        # Ensure we no longer emit a wide window that includes unrelated prefix text.
        assert "والله يعلم وأنتم لا تعلمون" not in hit.original_text
        assert hit.original_text.startswith("اذا ابتلاه")

    def test_common_short_fragment_does_not_emit_partial(self):
        chunk = "إن شاء الله إن شاء الله إن شاء الله"
        opts = StreamingQuranMatcherOptions(
            min_confidence=0.8,
            asr_tolerant=True,
            detect_partial_ayahs=True,
        )
        matcher = StreamingQuranMatcher(opts)
        r = matcher.process_chunk(chunk)
        rf = matcher.flush()
        partial_hits = r.partial_ayahs + rf.partial_ayahs
        assert partial_hits == []

    def test_main_indexed_v1_mode_matches_chunk_indexed_scan(self):
        chunk = "يقول الله تعالى يا أيها الذين آمنوا كتب عليكم الصيام كما كتب على الذين من قبلكم لعلكم تتقون"
        opts = StreamingQuranMatcherOptions(
            matcher_mode="main_indexed_v1",
            min_confidence=0.8,
            asr_tolerant=True,
        )
        matcher = StreamingQuranMatcher(opts)
        validator = QuranValidator(
            ValidatorOptions(
                fuzzy_threshold=max(0.6, opts.min_confidence * 0.9),
                include_partial=False,
                asr_tolerant=opts.asr_tolerant,
            )
        )

        expected = [
            h.get("reference")
            for h in validator.scan_for_verses(
                chunk,
                min_words=opts.min_words,
                max_words=opts.max_words,
                confidence_threshold=opts.min_confidence,
            )
            if h.get("reference")
        ]
        result = matcher.process_chunk(chunk)
        got = [h.reference for h in result.complete_verses if h.reference]

        assert got == expected
        assert result.stats.get("mode_main_indexed") == 1
