from __future__ import annotations

import logging
import random

import shortuuid

from backends.editor.connections.db_handler_registry import get_handler_for_graph
from solutions.graph.models import GraphAlreadyExistsError, GraphMetadata, VersionedGraphMetadata
from stores.graph_metadata_store import GraphMetadataStore

ADJECTIVES = [
    "brave",
    "clever",
    "dazzling",
    "eager",
    "fancy",
    "glorious",
    "happy",
    "inventive",
    "jolly",
    "kind",
    "lively",
    "mighty",
    "noble",
    "quick",
    "radiant",
    "silent",
    "trusty",
    "unique",
    "vivid",
    "witty",
]

NOUNS = [
    "eagle",
    "tiger",
    "panda",
    "falcon",
    "lion",
    "wolf",
    "phoenix",
    "griffin",
    "unicorn",
    "dragon",
    "panther",
    "raven",
    "dolphin",
    "orca",
    "sparrow",
    "turtle",
    "whale",
    "shark",
    "vulture",
    "falcon",
]


def create_graph(store: GraphMetadataStore) -> VersionedGraphMetadata:
    """
    Raises:
        GraphAlreadyExistsError
        GraphMetadataStoreError
    """
    max_attempts = 10
    attempt = 0
    while True:
        graph_id = shortuuid.uuid()

        metadata = GraphMetadata(
            id=graph_id,
            name=f"{random.choice(ADJECTIVES)} {random.choice(NOUNS)}",
            nodes={},
            edges={},
            nodes_view={},
            edges_view={},
            sampling={"sampling": "head", "max_rows": 1000},
            cypher_queries=[],
            connection={"type": "kuzu"},  # Default connection to Kuzu
        )

        try:
            new_graph_metadata = store.create(metadata)
            break
        except GraphAlreadyExistsError:
            attempt += 1
            logging.info(
                "Graph ID collision detected for '%s'. Retrying with a new id (attempt %d/%d).",
                graph_id,
                attempt,
                max_attempts,
            )
            if attempt >= max_attempts:
                raise

    db_handler = get_handler_for_graph(graph_id)
    db_handler.create_db()

    return new_graph_metadata
