from usecases.clear_work_space_document_use_case import (
    ClearWorkSpaceDocumentUseCase,
)
from geometric_feasibility_predicate.usecases.get_collision_at_primitive_use_case import (
    GetCollisionAtPrimitiveUseCase,
)
from usecases.render_primitive_use_case import RenderPrimitiveUseCase
from usecases.get_part_primitive_coordinates_use_case import (
    GetPartPrimitiveCoordinatesUseCase,
)
from usecases.init_parts_parse_use_case import (
    InitPartsParseUseCase,
)
from usecases.render_primitives_scenario import RenderPrimitivesScenario
from usecases.get_first_detail_use_case import GetFirstDetailUseCase
from geometric_feasibility_predicate.usecases.get_all_parts_labels_use_case import (
    GetAllPartsLabelsUseCase,
)
from models.adjacency_matrix_model import AdjacencyMatrixModel
from repository.freecad_repository import FreeCadRepository


class CadAdjacencyMatrixModel:
    """Class for handling adjacency matrix creation scenario

    Returns:
        dict: adjacency matrix
    """

    def primitiveMatrix(self):
        """get matrix of primitives"""
        # Получение матрицы
        matrix = RenderPrimitivesScenario(
            InitPartsParseUseCase(),
            GetPartPrimitiveCoordinatesUseCase(),
            RenderPrimitiveUseCase(),
            GetCollisionAtPrimitiveUseCase(),
            ClearWorkSpaceDocumentUseCase(),
        ).call()
        return AdjacencyMatrixModel(
            all_parts=GetAllPartsLabelsUseCase().call(),
            first_detail=GetFirstDetailUseCase().call(),
            matrix=matrix,
        )

    # Матрица основанная на соприкосновении обьектов

    def matrixBySurfaces(self):
        """Adjacency matrix by touches between parts

        Returns:
            dict: adjacency matrix
        """
        matrix = {}
        for part in FreeCadRepository().getAllSolids():
            matrix[part.Label] = []
            for nextPart in FreeCadRepository().getAllSolids():
                if part.Label != nextPart.Label:
                    # Вычисление соприконсоновения площади деталей
                    collisionResult: int = int(
                        part.Shape.distToShape(nextPart.Shape)[0]
                    )

                    if collisionResult == 0:
                        matrix[part.Label].append(nextPart.Label)

        return AdjacencyMatrixModel(
            all_parts=GetAllPartsLabelsUseCase().call(),
            first_detail=GetFirstDetailUseCase().call(),
            matrix=matrix,
        )
