"""
Video Translator Builder - Конструктор переводчика видео
"""

from typing import Dict, Any, Optional, Callable, List
from pathlib import Path
from .core import FrameworkCore, ProcessingContext
from .pipeline import ProcessingPipeline, StandardPipelines, PipelineBuilder
from .config import FrameworkConfig

class VideoTranslatorBuilder:
    """Строитель для создания настроенного переводчика видео"""

    def __init__(self):
        self.config = FrameworkConfig()
        self.core = FrameworkCore()
        self.pipeline: Optional[ProcessingPipeline] = None
        self._components_config: Dict[str, Dict[str, Any]] = {}

    def with_config(self, config: FrameworkConfig) -> 'VideoTranslatorBuilder':
        """Установка конфигурации"""
        self.config = config
        self.core = FrameworkCore(config.to_dict())
        return self

    def with_default_config(self, **overrides) -> 'VideoTranslatorBuilder':
        """Использование конфигурации по умолчанию с переопределениями"""
        config_dict = self.config.to_dict()
        config_dict.update(overrides)
        self.config = FrameworkConfig.from_dict(config_dict)
        self.core = FrameworkCore(self.config.to_dict())
        return self

    def with_speech_engine(self, engine: str, **config) -> 'VideoTranslatorBuilder':
        """Настройка движка распознавания речи"""
        self._components_config['speech_recognition'] = {
            'engine': engine,
            **config
        }
        return self

    def with_translation_service(self, service: str, **config) -> 'VideoTranslatorBuilder':
        """Настройка сервиса перевода"""
        self._components_config['translation'] = {
            'service': service,
            **config
        }
        return self

    def with_tts_engine(self, engine: str, **config) -> 'VideoTranslatorBuilder':
        """Настройка движка синтеза речи"""
        self._components_config['speech_synthesis'] = {
            'engine': engine,
            **config
        }
        return self

    def with_video_settings(self, **config) -> 'VideoTranslatorBuilder':
        """Настройка параметров видео"""
        self._components_config['video'] = config
        return self

    def with_pipeline(self, pipeline: ProcessingPipeline) -> 'VideoTranslatorBuilder':
        """Установка кастомного пайплайна"""
        self.pipeline = pipeline
        return self

    def with_standard_pipeline(self, pipeline_type: str = "full") -> 'VideoTranslatorBuilder':
        """Использование стандартного пайплайна"""
        speech_config = self._components_config.get('speech_recognition', {})
        translation_config = self._components_config.get('translation', {})
        tts_config = self._components_config.get('speech_synthesis', {})

        if pipeline_type == "full":
            self.pipeline = StandardPipelines.full_translation_pipeline(
                speech_engine=speech_config.get('engine', 'auto'),
                translation_service=translation_config.get('service', 'deepl'),
                tts_engine=tts_config.get('engine', 'auto')
            )
        elif pipeline_type == "original":
            # Используем оригинальную систему video_translator.py
            video_config = self._components_config.get('video', {})

            # Преобразуем конфигурацию GUI в параметры компонента
            component_config = {**speech_config, **translation_config, **tts_config, **video_config}

            # Добавляем настройки субтитров из основной конфигурации
            if hasattr(self.config, 'video_processing'):
                component_config['generate_subtitles'] = getattr(self.config.video_processing, 'subtitle_generation', True)
            else:
                component_config['generate_subtitles'] = True  # По умолчанию включены

            self.pipeline = StandardPipelines.original_system_pipeline(**component_config)
        elif pipeline_type == "transcription":
            self.pipeline = StandardPipelines.transcription_only_pipeline(
                speech_engine=speech_config.get('engine', 'auto')
            )
        elif pipeline_type == "translation":
            self.pipeline = StandardPipelines.translation_only_pipeline(
                translation_service=translation_config.get('service', 'deepl')
            )
        else:
            raise ValueError(f"Unknown pipeline type: {pipeline_type}")

        return self

    def with_custom_pipeline(self) -> PipelineBuilder:
        """Создание кастомного пайплайна через билдер"""
        builder = PipelineBuilder("custom")

        # Применяем конфигурации компонентов
        def finalize_and_set(original_build):
            def wrapper():
                pipeline = original_build()
                self.pipeline = pipeline
                return self
            return wrapper

        builder.build = finalize_and_set(builder.build)
        return builder

    def build(self) -> 'VideoTranslator':
        """Создание настроенного переводчика"""
        if not self.pipeline:
            # Используем стандартный пайплайн по умолчанию
            self.with_standard_pipeline("full")

        return VideoTranslator(self.core, self.pipeline, self.config)

class VideoTranslator:
    """Основной класс переводчика видео"""

    def __init__(self, core: FrameworkCore, pipeline: ProcessingPipeline, config: FrameworkConfig):
        self.core = core
        self.pipeline = pipeline
        self.config = config
        self.logger = core.logger

    def translate(
        self,
        input_file: str | Path,
        output_file: str | Path,
        source_language: str = "auto",
        target_language: str = "ru",
        progress_callback: Optional[Callable] = None,
        **kwargs
    ) -> ProcessingContext:
        """
        Перевод видео

        Args:
            input_file: Путь к исходному видео
            output_file: Путь для сохранения результата
            source_language: Исходный язык (auto для автоопределения)
            target_language: Целевой язык
            progress_callback: Функция для отслеживания прогресса
            **kwargs: Дополнительные настройки

        Returns:
            ProcessingContext: Контекст с результатами обработки
        """
        # Создание контекста обработки
        context = ProcessingContext(
            input_file=Path(input_file),
            output_file=Path(output_file),
            source_language=source_language,
            target_language=target_language,
            progress_callback=progress_callback,
            settings=kwargs
        )

        self.logger.info(f"Starting translation: {input_file} -> {output_file}")
        self.logger.info(f"Languages: {source_language} -> {target_language}")

        try:
            # Выполнение пайплайна
            result = self.pipeline.execute(context)
            self.logger.info("Translation completed successfully")
            return result

        except Exception as e:
            self.logger.error(f"Translation failed: {e}")
            raise

    def translate_batch(
        self,
        files: List[Dict[str, Any]],
        progress_callback: Optional[Callable] = None
    ) -> List[ProcessingContext]:
        """
        Пакетный перевод файлов

        Args:
            files: Список файлов с параметрами обработки
            progress_callback: Функция для отслеживания общего прогресса

        Returns:
            List[ProcessingContext]: Результаты обработки всех файлов
        """
        results = []
        total_files = len(files)

        for i, file_config in enumerate(files):
            self.logger.info(f"Processing file {i+1}/{total_files}: {file_config.get('input_file')}")

            # Прогресс для отдельного файла
            def file_progress(stage, progress):
                if progress_callback:
                    overall_progress = (i / total_files + progress / 100 / total_files) * 100
                    progress_callback(f"File {i+1}/{total_files}: {stage}", overall_progress)

            try:
                result = self.translate(
                    progress_callback=file_progress,
                    **file_config
                )
                results.append(result)

            except Exception as e:
                self.logger.error(f"Failed to process file {file_config.get('input_file')}: {e}")
                # Создаем контекст с ошибкой
                error_context = ProcessingContext(
                    input_file=Path(file_config['input_file']),
                    output_file=Path(file_config['output_file'])
                )
                error_context.metadata['error'] = str(e)
                results.append(error_context)

        return results

    def get_pipeline_info(self) -> Dict[str, Any]:
        """Получение информации о пайплайне"""
        return {
            'name': self.pipeline.name,
            'steps': self.pipeline.get_step_names(),
            'step_count': len(self.pipeline.steps)
        }

    def get_config_info(self) -> Dict[str, Any]:
        """Получение информации о конфигурации"""
        return self.config.to_dict()

# Фабричные методы для быстрого создания
class VideoTranslatorFactory:
    """Фабрика для создания переводчиков с предустановленными конфигурациями"""

    @staticmethod
    def create_basic() -> VideoTranslator:
        """Создание базового переводчика"""
        return (VideoTranslatorBuilder()
                .with_standard_pipeline("full")
                .build())

    @staticmethod
    def create_fast() -> VideoTranslator:
        """Создание быстрого переводчика (менее точный)"""
        return (VideoTranslatorBuilder()
                .with_speech_engine("whisper", model="tiny")
                .with_tts_engine("pyttsx3")
                .with_standard_pipeline("full")
                .build())

    @staticmethod
    def create_accurate() -> VideoTranslator:
        """Создание точного переводчика (медленнее)"""
        return (VideoTranslatorBuilder()
                .with_speech_engine("whisper", model="large")
                .with_translation_service("deepl")
                .with_tts_engine("google")
                .with_standard_pipeline("full")
                .build())

    @staticmethod
    def create_transcription_only() -> VideoTranslator:
        """Создание переводчика только для транскрипции"""
        return (VideoTranslatorBuilder()
                .with_standard_pipeline("transcription")
                .build())