# pylint: disable=import-outside-toplevel

"""Formatter registry for processor results.

Formatters transform ProcessorResult into human-readable formats for LanceDB storage
and output generation.
"""

import functools
from dataclasses import dataclass, field
from typing import Dict, Callable, Any
from mini_videorag.core.processor import ProcessorResult


@dataclass
class FormattedOutput:
    """Output from a processor formatter.

    Attributes:
        summary_line: Concise one-line summary (e.g., "BRANDS: linkedin, google")
        content_text: Main content text (e.g., full transcript, OCR text)
        detail_line: Technical details (e.g., "confidence_threshold=0.3 | frames=10")
        is_empty: True if processor produced no meaningful output
        rag_metadata: Optional dict of structured fields for VideoRAG/LanceDB
        vlm_context: Optional pre-formatted text snippet for VLM context
    """

    summary_line: str
    content_text: str
    detail_line: str
    is_empty: bool
    rag_metadata: Dict[str, Any] = field(default_factory=dict)
    vlm_context: str = ""  # Processor's contribution to VLM prompt


# Global formatter registry
FORMATTER_REGISTRY: Dict[str, Callable[[ProcessorResult], FormattedOutput]] = {}


def register_formatter(processor_name: str):
    """Decorator to register a formatter function.

    Usage:
        @register_formatter("brand_detection")
        def format_brand_detection(result: ProcessorResult) -> FormattedOutput:
            ...
    """

    def decorator(func: Callable[[ProcessorResult], FormattedOutput]):
        FORMATTER_REGISTRY[processor_name] = func
        return func

    return decorator


def get_formatter(processor_name: str) -> Callable[[ProcessorResult], FormattedOutput]:
    """Get formatter for processor, falls back to default if not found."""
    return FORMATTER_REGISTRY.get(processor_name, default_formatter)


def default_formatter(result: ProcessorResult) -> FormattedOutput:
    """Fallback formatter for unknown processors."""
    name = result.processor_name.upper()
    if not result.success:
        return FormattedOutput(
            summary_line=f"{name}: failed",
            content_text="",
            detail_line=f"error={result.error}",
            is_empty=True,
        )
    return FormattedOutput(
        summary_line=f"{name}: ok",
        content_text="",
        detail_line="success",
        is_empty=False,
    )


@functools.lru_cache(maxsize=1)
def load_all_formatters():
    """Import all formatter modules to trigger registration.

    This ensures all formatters are registered before use.
    Formatters are imported directly (not through __init__.py) to avoid
    loading heavy processor dependencies.

    Note: This function is cached and will only execute once, even if called
    multiple times. This provides thread-safe, lazy initialization without
    requiring external state management.
    """
    import importlib

    formatter_modules = [
        "mini_videorag.processors.transcription.formatter",
        "mini_videorag.processors.ocr.formatter",
        "mini_videorag.processors.brand_detection.formatter",
        "mini_videorag.processors.music_detection.formatter",
        "mini_videorag.processors.person_detection.formatter",
        "mini_videorag.processors.object_detection.formatter",
        "mini_videorag.processors.content_safety.formatter",
        "mini_videorag.processors.frame_extraction.formatter",
        "mini_videorag.processors.subtitle_check.formatter",
        "mini_videorag.processors.subtitle_check.presence_formatter",
    ]

    for module_path in formatter_modules:
        try:
            importlib.import_module(module_path)
        except ImportError:
            pass
