from __future__ import annotations

import hashlib
from abc import ABC, abstractmethod

from graph.connections.connection_info import AbstractConnectionInfo
from graph.connections.db_handler import DbHandler
from solutions.graph.models import ExplorerMetadata


class Colorizer:
    @staticmethod
    def hash_to_index(input_string: str, num_colors: int) -> int:
        hash_object = hashlib.md5(input_string.encode())
        hash_int = int(hash_object.hexdigest(), 16)
        return hash_int % num_colors

    @staticmethod
    def string_to_beautiful_color(input_string: str) -> str:
        palette = [
            "#1f77b4",
            "#ff7f0e",
            "#2ca02c",
            "#d62728",
            "#9467bd",
            "#8c564b",
            "#e377c2",
            "#7f7f7f",
            "#bcbd22",
            "#17becf",
        ]
        return palette[Colorizer.hash_to_index(input_string, len(palette))]


class MetadataBuilder(ABC):
    """Abstract builder for explorer metadata for a specific DB implementation."""

    def __init__(self, db_handler: DbHandler, conn_info: AbstractConnectionInfo):
        self.db_handler = db_handler
        self.conn_info = conn_info

    @abstractmethod
    def build(self) -> ExplorerMetadata:
        """Build and return ExplorerMetadata."""

    @abstractmethod
    def get_nodes_view(self, node_definitions: list) -> dict:
        pass

    @abstractmethod
    def get_edges_view(self, edge_definitions: list) -> dict:
        pass
