from typing import Dict, List, Optional, Set, Union

from src.DiagramProcessor import DrawIOParser as DrawIOOriginalParser
from src.DiagramProcessorLite import DrawIOParser as DBeaverParser



class DrawIOAdapterForDBeaver(DBeaverParser):
    """Адаптер для DBeaverParser, чтобы предоставить интерфейс, совместимый с
    DrawIOParser."""

    def get_tables_and_fields(self) -> Dict[str, List[str]]:
        """Возвращает словарь таблиц и их полей, совместимый с форматом
        DrawIOParser."""
        return self.get_tables()

    def get_table_relationships(self) -> Dict[str, List[str]]:
        """Возвращает словарь связей между таблицами, совместимый с форматом
        DrawIOParser."""
        return self.get_relationships()

    def get_tables_without_relations(self) -> Set[str]:
        """Возвращает множество таблиц без связей."""
        relations = self.get_relationships()
        related_tables = set()
        for source, targets in relations.items():
            related_tables.add(source)
            related_tables.update(targets)

        all_tables = set(self.get_tables().keys())
        return all_tables - related_tables

    @staticmethod
    def parse_schema(json_data: Dict[str, List[str]]) -> Dict[str, Dict[str, str]]:
        """Преобразует формат данных таблиц от DBeaverParser в формат,
        совместимый с DrawIOParser."""
        result_schema = {}

        for table_name, columns in json_data.items():
            result_schema[table_name] = {}

            for column_info in columns:
                if ': ' in column_info:
                    parts = column_info.split(': ', 1)
                    if len(parts) == 2:
                        column_name = parts[0].strip()
                        column_type = parts[1].strip()

                        if column_name.startswith('PK ') or column_name.startswith('FK '):
                            result_schema[table_name][column_name] = column_type
                        else:
                            result_schema[table_name][column_name] = column_type
                else:
                    result_schema[table_name][column_info] = 'unknown'

        return result_schema


class DiagramProcessorFactory:
    """Фабрика для создания парсеров диаграмм различных типов."""

    @staticmethod
    def create_parser(
        diagram_type: str,
        file_path: Optional[str] = None,
    ) -> Union[DrawIOOriginalParser, DrawIOAdapterForDBeaver]:
        """Создает и возвращает экземпляр парсера в зависимости от типа
        диаграммы.

        Args:
            diagram_type (str): Тип диаграммы ('drawio' или 'dbeaver')
            file_path (str, optional): Путь к файлу диаграммы

        Returns:
            Union[DrawIOOriginalParser, DrawIOAdapterForDBeaver]: Экземпляр парсера

        Raises:
            ValueError: Если указан неподдерживаемый тип диаграммы
        """
        if diagram_type.lower() == 'drawio':
            return DrawIOOriginalParser(file_path)
        elif diagram_type.lower() == 'dbeaver':
            parser = DrawIOAdapterForDBeaver(file_path)
            if file_path:
                parser.process_all()
            return parser
        else:
            raise ValueError(f"Неподдерживаемый тип диаграммы: {diagram_type}. Используйте 'drawio' или 'dbeaver'.")
