"""Media service orchestrator for Trax platform.

This module provides a unified interface for media operations by orchestrating
specialized services for download, preprocessing, database operations, and pipeline management.
"""

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

from ..base.services import BaseService
from ..repositories.media_repository import MediaRepositoryProtocol, create_media_repository
from ..database.models import MediaFile
from .media_types import (
    MediaFileInfo,
    MediaServiceProtocol,
    ProgressCallback,
    TelemetryData,
)
from .media_download import MediaDownloadService
from .media_preprocessing import MediaPreprocessingService
from .media_database import MediaDatabaseService
from .media_pipeline import MediaPipelineService

logger = logging.getLogger(__name__)


class MediaService(BaseService):
    """Unified media service that orchestrates specialized services."""

    def __init__(self, config: Optional[Dict[str, Any]] = None, media_repository: Optional[MediaRepositoryProtocol] = None):
        super().__init__("media_service", config)
        
        # Initialize specialized services
        self.download_service = MediaDownloadService(config)
        self.preprocessing_service = MediaPreprocessingService(config)
        self.database_service = MediaDatabaseService(media_repository)
        self.pipeline_service = MediaPipelineService(
            self.download_service,
            self.preprocessing_service,
            self.database_service,
            config
        )

    async def _initialize_impl(self) -> None:
        """Initialize the media service and all sub-services."""
        await self.pipeline_service.initialize()

    # Delegate to download service
    async def download_media(self, url: str, output_dir: Path, progress_callback: Optional[ProgressCallback] = None) -> MediaFileInfo:
        """Download media from URL to local directory."""
        return await self.download_service.download_media(url, output_dir, progress_callback)

    # Delegate to preprocessing service
    async def preprocess_audio(self, input_path: Path, output_path: Path, progress_callback: Optional[ProgressCallback] = None) -> bool:
        """Convert audio to 16kHz mono WAV format for Whisper processing."""
        return await self.preprocessing_service.preprocess_audio(input_path, output_path, progress_callback)

    async def validate_file_size(self, file_path: Path, max_size_mb: int = 500) -> bool:
        """Validate that file size is within limits."""
        return await self.preprocessing_service.validate_file_size(file_path, max_size_mb)

    async def check_audio_quality(self, audio_path: Path) -> bool:
        """Check if audio file has valid content (not silent, duration >0.1s)."""
        return await self.preprocessing_service.check_audio_quality(audio_path)

    async def get_media_info(self, file_path: Path) -> Dict[str, Any]:
        """Get media file information using FFmpeg."""
        return await self.preprocessing_service.get_media_info(file_path)

    # Delegate to database service
    async def create_media_file_record(self, media_info: MediaFileInfo, youtube_video_id: Optional[UUID] = None) -> MediaFile:
        """Create a media file record in the database."""
        return await self.database_service.create_media_file_record(media_info, youtube_video_id)

    async def update_media_file_status(self, media_id: UUID, status: str) -> Optional[MediaFile]:
        """Update media file status in the database."""
        return await self.database_service.update_media_file_status(media_id, status)

    async def get_media_file_by_id(self, media_id: UUID) -> Optional[MediaFile]:
        """Get media file by ID from the database."""
        return await self.database_service.get_media_file_by_id(media_id)

    async def get_pending_media_files(self, limit: int = 50) -> List[MediaFile]:
        """Get pending media files from the database."""
        return await self.database_service.get_pending_media_files(limit)

    async def get_ready_media_files(self, limit: int = 50) -> List[MediaFile]:
        """Get ready media files from the database."""
        return await self.database_service.get_ready_media_files(limit)

    # Delegate to pipeline service
    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."""
        return await self.pipeline_service.process_media_pipeline(url, output_dir, youtube_video_id, progress_callback)

    # Telemetry aggregation
    def get_telemetry_data(self) -> List[TelemetryData]:
        """Get aggregated telemetry data from all services."""
        all_telemetry = []
        all_telemetry.extend(self.download_service.get_telemetry_data())
        all_telemetry.extend(self.preprocessing_service.get_telemetry_data())
        all_telemetry.extend(self.pipeline_service.get_telemetry_data())
        return all_telemetry

    def clear_telemetry_data(self) -> None:
        """Clear telemetry data from all services."""
        self.download_service.clear_telemetry_data()
        self.preprocessing_service.clear_telemetry_data()
        self.pipeline_service.clear_telemetry_data()


# Factory function for creating media service instances
def create_media_service(config: Optional[Dict[str, Any]] = None, media_repository: Optional[MediaRepositoryProtocol] = None) -> MediaService:
    """Create a new MediaService instance."""
    return MediaService(config, media_repository)
