"""
Graph API module
提供图数据库操作的API接口
"""

import logging

from flask import jsonify, request

from app.api.graph import bp
from app.core.graph import (
    create_or_get_node,
    create_relationship,
    execute_cypher_query,
    get_subgraph,
)
from app.models.result import failed, success

logger = logging.getLogger("app")


# 查询图数据
@bp.route("/query", methods=["POST"])
def query_graph():
    """
    执行自定义Cypher查询

    Args (通过JSON请求体):
        cypher (str): Cypher查询语句
        params (dict, optional): 查询参数

    Returns:
        JSON: 包含查询结果的响应
    """
    try:
        # 获取查询语句
        cypher = request.json.get("cypher", "") if request.json is not None else ""
        params = request.json.get("params", {}) if request.json is not None else {}

        if not cypher:
            return jsonify(failed("查询语句不能为空"))

        # 执行查询
        data = execute_cypher_query(cypher, params)
        return jsonify(success(data))
    except Exception as e:
        logger.error(f"图数据查询失败: {str(e)}")
        return jsonify(failed(str(e)))


# 创建节点
@bp.route("/node/create", methods=["POST"])
def create_node():
    """
    创建新节点

    Args (通过JSON请求体):
        labels (list): 节点标签列表
        properties (dict): 节点属性

    Returns:
        JSON: 包含创建的节点信息的响应
    """
    try:
        # 获取节点信息
        labels = request.json.get("labels", []) if request.json is not None else []
        properties = (
            request.json.get("properties", {}) if request.json is not None else {}
        )

        if not labels:
            return jsonify(failed("节点标签不能为空"))

        # 构建标签字符串
        label = ":".join(labels)

        # 创建节点
        node_id = create_or_get_node(label, **properties)

        # 查询创建的节点
        cypher = f"MATCH (n) WHERE id(n) = {node_id} RETURN n"
        result = execute_cypher_query(cypher)

        if result and len(result) > 0:
            return jsonify(success(result[0]))
        else:
            return jsonify(failed("节点创建失败"))
    except Exception as e:
        logger.error(f"创建节点失败: {str(e)}")
        return jsonify(failed(str(e)))


# 创建关系
@bp.route("/relationship/create", methods=["POST"])
def create_rel():
    """
    创建节点间的关系

    Args (通过JSON请求体):
        startNodeId (int): 起始节点ID
        endNodeId (int): 结束节点ID
        type (str): 关系类型
        properties (dict, optional): 关系属性

    Returns:
        JSON: 包含创建的关系信息的响应
    """
    try:
        # 获取关系信息
        start_node_id = (
            request.json.get("startNodeId") if request.json is not None else None
        )
        end_node_id = (
            request.json.get("endNodeId") if request.json is not None else None
        )
        rel_type = request.json.get("type") if request.json is not None else None
        properties = (
            request.json.get("properties", {}) if request.json is not None else {}
        )

        if not all([start_node_id, end_node_id, rel_type]):
            return jsonify(failed("关系参数不完整"))

        # 创建关系
        rel_id = create_relationship(start_node_id, end_node_id, rel_type, **properties)

        if rel_id:
            # 查询创建的关系
            cypher = f"MATCH ()-[r]-() WHERE id(r) = {rel_id} RETURN r"
            result = execute_cypher_query(cypher)

            if result and len(result) > 0:
                return jsonify(success(result[0]))

        return jsonify(failed("关系创建失败"))
    except Exception as e:
        logger.error(f"创建关系失败: {str(e)}")
        return jsonify(failed(str(e)))


# 获取图谱数据
@bp.route("/subgraph", methods=["POST"])
def get_graph_data():
    """
    获取子图数据

    Args (通过JSON请求体):
        nodeIds (list): 节点ID列表
        relationshipTypes (list, optional): 关系类型列表
        maxDepth (int, optional): 最大深度，默认为1

    Returns:
        JSON: 包含节点和关系的子图数据
    """
    try:
        # 获取请求参数
        node_ids = request.json.get("nodeIds", []) if request.json is not None else []
        rel_types = (
            request.json.get("relationshipTypes", [])
            if request.json is not None
            else []
        )
        max_depth = request.json.get("maxDepth", 1) if request.json is not None else 1

        if not node_ids:
            return jsonify(failed("节点ID列表不能为空"))

        # 获取子图
        graph_data = get_subgraph(node_ids, rel_types, max_depth)

        return jsonify(success(graph_data))
    except Exception as e:
        logger.error(f"获取图谱数据失败: {str(e)}")
        return jsonify(failed(str(e)))
