import dataiku

from backends.explorer.discovery.info_registry import get_connection_info_registry
from graph.connections.neo4j.preset import Neo4jPresetConfig
from graph.exploration.queries.neo4j.list_databases import list_databases as list_neo4j_databases
from recipes.explore_graph.utils import get_database_type_from_folder


def do(payload, config, plugin_config, inputs):
    parameter_name = payload["parameterName"]
    root_model = payload.get("rootModel", {})
    db_folder_id = root_model.get("db_folder_id")
    result = {"choices": []}

    if parameter_name == "database_type":
        if db_folder_id:
            folder = dataiku.Folder(db_folder_id)
            database_type = get_database_type_from_folder(folder)
            if not database_type:
                result = {"choices": []}
            else:
                label = "Built-in" if database_type == "kuzu" else "Neo4j"
                result = {"choices": [{"value": database_type, "label": label}]}
        else:
            # When no input folder is selected, only direct Neo4j access is available.
            result = {"choices": [{"value": "unmanaged_neo4j", "label": "Neo4j (unmanaged)"}]}
    elif parameter_name == "database_name":
        if db_folder_id:
            folder = dataiku.Folder(db_folder_id)
            conn_info_registry = get_connection_info_registry(db_folders=[folder])
            conn_info_list = conn_info_registry.list_connection_info()

            if not conn_info_list:
                raise ValueError("No graph database found in the input folder.")
            if len(conn_info_list) > 1:
                raise ValueError("Multiple graph databases found in the input folder, please select a folder with a single graph.")

            conn_info = conn_info_list[0]
            if conn_info.type != "neo4j":
                return result
            result = {"choices": [{"value": conn_info.database_name, "label": conn_info.database_name}]}
        else:
            neo4j_configuration = config.get("neo4j_preset")
            if not neo4j_configuration:
                return result

            neo4j_configuration = Neo4jPresetConfig.from_dict(neo4j_configuration)
            database_names = list_neo4j_databases(
                uri=neo4j_configuration.neo4j_uri,
                username=neo4j_configuration.neo4j_username,
                password=neo4j_configuration.get_neo4j_password(),
            )
            result = {"choices": [{"value": db_name, "label": db_name} for db_name in sorted(database_names)]}

    else:
        raise Exception(f"Unexpected parameter name '{parameter_name}'.")

    return result
