from __future__ import annotations

import logging

from flask import Blueprint

from backends.explorer.queries.explorer_data import (
    run_cypher_query,
)
from backends.explorer.queries.params import ExplorerRunCypherParams
from backends.explorer.utils.connections import get_webapp_db_handler
from backends.explorer.utils.webapp_config import webapp_config
from backends.utils import return_ok, validate_params
from graph.exploration.cypher_graph_view import CypherQueryExecutionException
from solutions.graph.models import PresetNotSetException

logger = logging.getLogger(__name__)

graph_cypher = Blueprint("data", __name__, url_prefix="/cypher")


@graph_cypher.route("/run", methods=["POST"])
@validate_params(ExplorerRunCypherParams)
def run_cypher(params: ExplorerRunCypherParams):
    """
    Executes a user-provided Cypher query against a graph snapshot.

    The query result is enriched with graph metadata before being returned.
    Handles specific exceptions for configuration and query execution errors.

    Args:
        params (ExplorerRunCypherParams): Validated query parameters.

    Returns:
        dict: OK response with query results (nodes, edges, table) or an error message.
    """
    try:
        db_handler, conn_info_registry = get_webapp_db_handler(params.snapshot_id)
        result = run_cypher_query(
            params,
            db_handler,
            conn_info_registry,
            timeout_seconds=webapp_config.db_query_timeout_seconds,
        )
        return return_ok(data=result)
    except PresetNotSetException as ex:
        raise ex
    except CypherQueryExecutionException as ex:
        logger.info(
            f"User query raised an error on saved configuration {params.snapshot_id}, '{params.query}'.", exc_info=True
        )
        return return_ok(data=str(ex))
    except Exception as ex:
        logger.exception(
            f"An unexpected error occured on saved configuration {params.snapshot_id}, '{params.query}'.", exc_info=True
        )
        return return_ok(data=str("An unexpected error occured."))
