import networkx as nx


class GraphProcessor:
    graph = None

    def __init__(self, adjacency_matrix):
        self.adjacency_matrix = adjacency_matrix
        self.graph = self.load_graph_from_data()

    def load_graph_from_data(self):
        G = nx.Graph()

        for part1, neighbors in self.adjacency_matrix.items():
            for neighbor in neighbors:
                G.add_edge(part1, neighbor)

        return G


class EdgeBetweensClustering:
    def __init__(self, graph):
        self.graph = graph.copy()
        self.clusters = []

    def cluster(self):
        while self.graph.number_of_edges() > 0:
            edge_betweens = nx.edge_betweenness_centrality(self.graph)
            max_betweens_edge = max(edge_betweens, key=edge_betweens.get)
            self.graph.remove_edge(*max_betweens_edge)
            components = list(nx.connected_components(self.graph))
            if components not in self.clusters:
                self.clusters.append(components)
        return []

    def get_clusters(self):
        return self.clusters


class ClusterisationSequenceUseCase:
    def call(self, adjacency_matrix):
        graph_processor = GraphProcessor(adjacency_matrix)
        G = graph_processor.load_graph_from_data()
        ebc = EdgeBetweensClustering(G)
        ebc.cluster()
        clusters = ebc.get_clusters()

        for i in range(len(clusters)):
            for j in range(len(clusters[i])):
                clusters[i][j] = list(clusters[i][j])

        # Создание списка последовательностей сборки
        assembly_sequences = []
        for cluster in clusters:
            sequence = []
            for component in cluster:
                sequence.extend(component)
            assembly_sequences.append(sequence)

        return assembly_sequences


# # Вызов функции
# adjacency_matrix = {
#     'body_down': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
#     'sol_gear': ['body_down', 'output_shaft', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002'],
#     'output_shaft': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up'],
#     'planet_gear': ['body_down', 'sol_gear', 'output_shaft'],
#     'planet_gear003': ['body_down', 'sol_gear', 'output_shaft'],
#     'planet_gear004': ['body_down', 'sol_gear', 'output_shaft'],
#     'planet_gear005': ['body_down', 'sol_gear', 'output_shaft'],
#     'planet_gear002': ['body_down', 'sol_gear', 'output_shaft'],
#     'body_up': ['body_down', 'output_shaft', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
#     'bolt': ['body_down', 'body_up'],
#     'bolt2': ['body_down', 'body_up'],
#     'bolt3': ['body_down', 'body_up'],
#     'bolt4': ['body_down', 'body_up']
# }
# print(adjacency_matrix)
# use_case = ClusterisationSequenceUseCase()
# assembly_sequences = use_case.call(adjacency_matrix)
# print(assembly_sequences)
