"""N-gram based subtitle presence detection processor."""

import logging
from typing import Optional, Tuple

from mini_videorag.core.processor import ProcessorResult
from mini_videorag.processors.subtitle_check.base import BaseSubtitleCheckProcessor

# Import helper functions from subtitle_check utils
from mini_videorag.processors.subtitle_check.utils import (
    calculate_subtitle_presence_score,
    check_language_mismatch,
)


# pylint: disable=broad-exception-caught, too-many-positional-arguments
class NgramSubtitleCheckProcessor(BaseSubtitleCheckProcessor):
    """
    Detect subtitle presence by comparing OCR and transcription using n-grams.

    This processor requires both OCR and transcription results to work.
    """

    def __init__(
        self,
        fuzzy: bool = True,
        text_similarity_threshold: float = 0.8,
        subtitle_presence_threshold: float = 0.20,
        min_ocr_frame_coverage: float = 0.85,
        n_gram_range: Tuple[int, int] = (2, 5),
    ):
        """
        Initialize n-gram subtitle check processor.

        Args:
            fuzzy: Enable fuzzy matching using Levenshtein distance
            text_similarity_threshold: Similarity threshold for fuzzy matching
            subtitle_presence_threshold: Threshold for determining subtitle presence
            min_ocr_frame_coverage: Minimum OCR frame coverage
            n_gram_range: Tuple (min, max) for n-gram generation (default: (2, 5))
        """
        self.fuzzy = fuzzy
        self.text_similarity_threshold = text_similarity_threshold
        self.subtitle_presence_threshold = subtitle_presence_threshold
        self.min_ocr_frame_coverage = min_ocr_frame_coverage
        self.n_gram_range = n_gram_range
        self.logger = logging.getLogger(__name__)

    @property
    def provider(self) -> str:
        """Provider name for this implementation."""
        return "ngram"

    def process(
        self,
        video_path: str,
        video_id: str,
        ocr_result: Optional[ProcessorResult] = None,
        transcription_result: Optional[ProcessorResult] = None,
        **kwargs,
    ) -> ProcessorResult:
        """
        Check for subtitle presence by comparing OCR and transcription results.

        Args:
            video_path: Path to video file (not used directly)
            video_id: Unique identifier
            ocr_result: ProcessorResult from OCR processor (required)
            transcription_result: ProcessorResult from transcription processor (required)
            **kwargs: Additional options

        Returns:
            ProcessorResult with subtitle presence score and analysis
        """
        try:
            if not ocr_result or not transcription_result:
                return ProcessorResult(
                    processor_name=self.name,
                    video_id=video_id,
                    success=False,
                    error="Both ocr_result and transcription_result are required",
                )

            if isinstance(ocr_result, dict):
                ocr_result = ProcessorResult(**ocr_result)
            if isinstance(transcription_result, dict):
                transcription_result = ProcessorResult(**transcription_result)

            # Check that both processors succeeded
            if not ocr_result.success or not transcription_result.success:
                return ProcessorResult(
                    processor_name=self.name,
                    video_id=video_id,
                    success=False,
                    error="OCR or transcription failed",
                )

            self.logger.info(f"Checking subtitle presence for video: {video_id}")

            transcript_text = transcription_result.data.get("english_transcript", "")
            if not transcript_text:
                transcript_text = transcription_result.data.get("original_transcript", "")

            ocr_tokens = ocr_result.data.get("filtered_tokens", [])

            lang = ocr_result.data.get("detected_language")
            if not lang:
                lang = transcription_result.data.get("detected_language", "en")

            language_info = check_language_mismatch(transcript_text, lang)

            frames_with_ocr = ocr_result.data.get("frames_with_text", 0)
            total_frames = ocr_result.data.get("frames_processed", 1)

            score, token_info = calculate_subtitle_presence_score(
                transcript_text=transcript_text,
                ocr_tokens=ocr_tokens,
                lang=lang,
                fuzzy=self.fuzzy,
                text_similarity_threshold=self.text_similarity_threshold,
                min_ocr_frame_coverage=self.min_ocr_frame_coverage,
                frames_with_ocr=frames_with_ocr,
                total_frames=total_frames,
                n_gram_range=self.n_gram_range,
            )

            has_subtitles = score >= self.subtitle_presence_threshold

            self.logger.info(
                f"Subtitles {'detected ✅' if has_subtitles else 'likely missing ❌'} "
                f"(score: {score:.2f}, threshold: {self.subtitle_presence_threshold})"
            )

            return ProcessorResult(
                processor_name=self.name,
                video_id=video_id,
                success=True,
                data={
                    "subtitle_presence_score": score,
                    "has_subtitles": has_subtitles,
                    "threshold": self.subtitle_presence_threshold,
                    **token_info,
                    **language_info,
                },
                metadata={
                    "provider": self.provider,
                    "lang": lang,
                    "fuzzy_matching": self.fuzzy,
                    "text_similarity_threshold": self.text_similarity_threshold,
                    "min_ocr_frame_coverage": self.min_ocr_frame_coverage,
                    "n_gram_range": self.n_gram_range,
                },
            )

        except Exception as e:
            return ProcessorResult(
                processor_name=self.name, video_id=video_id, success=False, error=str(e)
            )
