"""Media pipeline orchestration service."""

import logging
from pathlib import Path
from typing import Any, Dict, List, Optional
from uuid import UUID

from ..base.services import BaseService
from ..database.models import MediaFile
from .media_types import (
    MediaFileInfo,
    MediaServiceProtocol,
    ProgressCallback,
    TelemetryData,
)
from .media_telemetry import MediaTelemetry, ProgressTracker

logger = logging.getLogger(__name__)


class MediaPipelineService(BaseService):
    """Orchestrates the complete media processing pipeline."""

    def __init__(
        self,
        download_service,
        preprocessing_service,
        database_service,
        config: Optional[Dict[str, Any]] = None,
    ):
        super().__init__("media_pipeline", config)
        self.download_service = download_service
        self.preprocessing_service = preprocessing_service
        self.database_service = database_service
        self.telemetry = MediaTelemetry()

    async def _initialize_impl(self) -> None:
        """Initialize the pipeline service."""
        # Initialize preprocessing service to check FFmpeg
        await self.preprocessing_service._initialize_impl()

    async def process_media_pipeline(
        self,
        url: str,
        output_dir: Path,
        youtube_video_id: Optional[UUID] = None,
        progress_callback: Optional[ProgressCallback] = None,
    ) -> MediaFile:
        """Complete media processing pipeline from download to ready."""
        telemetry = self.telemetry.create_telemetry("pipeline")

        try:
            # Step 1: Download media
            if progress_callback:
                progress = ProgressTracker.create_processing_progress(
                    stage="pipeline",
                    current_step=1,
                    total_steps=4,
                    status="downloading",
                    message="Starting media download",
                    start_time=telemetry.start_time,
                )
                ProgressTracker.notify_progress(progress, progress_callback)

            media_info = await self.download_service.download_media(url, output_dir, progress_callback)

            # Step 2: Create database record
            if progress_callback:
                progress = ProgressTracker.create_processing_progress(
                    stage="pipeline",
                    current_step=2,
                    total_steps=4,
                    status="creating_record",
                    message="Creating database record",
                    start_time=telemetry.start_time,
                )
                ProgressTracker.notify_progress(progress, progress_callback)

            media_file = await self.database_service.create_media_file_record(media_info, youtube_video_id)

            # Step 3: Update status to downloading
            await self.database_service.update_media_file_status(media_file.id, "downloading")

            # Step 4: Preprocess audio
            if progress_callback:
                progress = ProgressTracker.create_processing_progress(
                    stage="pipeline",
                    current_step=3,
                    total_steps=4,
                    status="preprocessing",
                    message="Preprocessing audio",
                    start_time=telemetry.start_time,
                )
                ProgressTracker.notify_progress(progress, progress_callback)

            input_file = Path(media_info.local_path)
            output_file = output_dir / f"processed_{media_info.filename}.wav"

            success = await self.preprocessing_service.preprocess_audio(input_file, output_file, progress_callback)

            # Step 5: Update final status
            if progress_callback:
                progress = ProgressTracker.create_processing_progress(
                    stage="pipeline",
                    current_step=4,
                    total_steps=4,
                    status="finalizing",
                    message="Finalizing processing",
                    start_time=telemetry.start_time,
                )
                ProgressTracker.notify_progress(progress, progress_callback)

            if success:
                await self.database_service.update_media_file_status(media_file.id, "ready")
                logger.info(f"Media pipeline completed successfully: {media_file.filename}")
            else:
                await self.database_service.update_media_file_status(media_file.id, "failed")
                logger.error(f"Media pipeline failed: {media_file.filename}")

            # Update telemetry
            self.telemetry.update_telemetry_success(telemetry)

            if progress_callback:
                progress = ProgressTracker.create_processing_progress(
                    stage="pipeline",
                    current_step=4,
                    total_steps=4,
                    status="completed" if success else "failed",
                    message="Pipeline completed successfully" if success else "Pipeline failed",
                    start_time=telemetry.start_time,
                    elapsed_time=telemetry.duration,
                )
                ProgressTracker.notify_progress(progress, progress_callback)

            return media_file

        except Exception as e:
            # Update telemetry with error information
            self.telemetry.update_telemetry_error(telemetry, e)

            logger.error(f"Media pipeline failed: {str(e)}")
            raise

    def get_telemetry_data(self) -> List[TelemetryData]:
        """Get telemetry data for monitoring."""
        return self.telemetry.get_telemetry_data()

    def clear_telemetry_data(self) -> None:
        """Clear telemetry data."""
        self.telemetry.clear_telemetry_data()
