package com.lingyue.graph.controller;

import com.lingyue.graph.dto.*;
import com.lingyue.graph.entity.GraphNode;
import com.lingyue.graph.entity.GraphRelation;
import com.lingyue.graph.service.GraphNodeService;
import com.lingyue.graph.service.GraphService;
import com.lingyue.common.domain.AjaxResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 图数据库控制器
 * 提供图节点和关系的 CRUD 操作
 *
 * @author lingyue
 * @since 2026-01-19
 */
@Slf4j
@RestController
@RequestMapping("/api/graph")
@RequiredArgsConstructor
@Tag(name = "图数据库", description = "图节点和关系管理接口")
public class GraphController {
    
    private final GraphService graphService;
    private final GraphNodeService graphNodeService;

    // ==================== 节点操作 ====================

    /**
     * 创建节点
     */
    @PostMapping("/nodes")
    @Operation(summary = "创建节点", description = "创建单个图节点")
    public AjaxResult<?> createNode(@RequestBody CreateNodeRequest request) {
        try {
            GraphNode node = graphNodeService.createNode(request);
            return AjaxResult.success(node);
        } catch (Exception e) {
            log.error("创建节点失败: {}", e.getMessage(), e);
            return AjaxResult.error("创建节点失败: " + e.getMessage());
        }
    }

    /**
     * 批量创建节点
     */
    @PostMapping("/nodes/batch")
    @Operation(summary = "批量创建节点", description = "批量创建图节点")
    public AjaxResult<?> batchCreateNodes(@RequestBody BatchCreateNodesRequest request) {
        try {
            List<GraphNode> nodes = graphNodeService.batchCreateNodes(request);
            return AjaxResult.success(nodes);
        } catch (Exception e) {
            log.error("批量创建节点失败: {}", e.getMessage(), e);
            return AjaxResult.error("批量创建节点失败: " + e.getMessage());
        }
    }

    /**
     * 获取节点
     */
    @GetMapping("/nodes/{nodeId}")
    @Operation(summary = "获取节点", description = "根据ID获取节点详情")
    public AjaxResult<?> getNode(
            @Parameter(description = "节点ID") @PathVariable String nodeId) {
        GraphNode node = graphNodeService.getNodeById(nodeId);
        if (node == null) {
            return AjaxResult.error("节点不存在: " + nodeId);
        }
        return AjaxResult.success(node);
    }

    /**
     * 获取文档的所有节点
     */
    @GetMapping("/documents/{documentId}/nodes")
    @Operation(summary = "获取文档节点", description = "获取指定文档的所有节点")
    public AjaxResult<?> getNodesByDocument(
            @Parameter(description = "文档ID") @PathVariable String documentId,
            @Parameter(description = "节点类型（可选）") @RequestParam(required = false) String type) {
        List<GraphNode> nodes;
        if (type != null && !type.isEmpty()) {
            nodes = graphNodeService.getNodesByDocumentIdAndType(documentId, type);
        } else {
            nodes = graphNodeService.getNodesByDocumentId(documentId);
        }
        return AjaxResult.success(nodes);
    }

    /**
     * 更新节点
     */
    @PutMapping("/nodes/{nodeId}")
    @Operation(summary = "更新节点", description = "更新节点信息")
    public AjaxResult<?> updateNode(
            @Parameter(description = "节点ID") @PathVariable String nodeId,
            @RequestBody CreateNodeRequest request) {
        try {
            GraphNode node = graphNodeService.updateNode(nodeId, request);
            return AjaxResult.success(node);
        } catch (Exception e) {
            log.error("更新节点失败: nodeId={}, error={}", nodeId, e.getMessage(), e);
            return AjaxResult.error("更新节点失败: " + e.getMessage());
        }
    }

    /**
     * 删除节点
     */
    @DeleteMapping("/nodes/{nodeId}")
    @Operation(summary = "删除节点", description = "删除节点及其相关关系")
    public AjaxResult<?> deleteNode(
            @Parameter(description = "节点ID") @PathVariable String nodeId) {
        try {
            graphNodeService.deleteNode(nodeId);
            return AjaxResult.success();
        } catch (Exception e) {
            log.error("删除节点失败: nodeId={}, error={}", nodeId, e.getMessage(), e);
            return AjaxResult.error("删除节点失败: " + e.getMessage());
        }
    }

    /**
     * 删除文档的所有节点
     */
    @DeleteMapping("/documents/{documentId}/nodes")
    @Operation(summary = "删除文档节点", description = "删除指定文档的所有节点及关系")
    public AjaxResult<?> deleteNodesByDocument(
            @Parameter(description = "文档ID") @PathVariable String documentId) {
        try {
            int count = graphNodeService.deleteNodesByDocumentId(documentId);
            return AjaxResult.success("删除成功", count);
        } catch (Exception e) {
            log.error("删除文档节点失败: documentId={}, error={}", documentId, e.getMessage(), e);
            return AjaxResult.error("删除文档节点失败: " + e.getMessage());
        }
    }

    // ==================== 关系操作 ====================

    /**
     * 创建关系
     */
    @PostMapping("/relations")
    @Operation(summary = "创建关系", description = "创建节点间的关系")
    public AjaxResult<?> createRelation(@RequestBody CreateRelationRequest request) {
        try {
            GraphRelation relation = graphNodeService.createRelation(request);
            return AjaxResult.success(relation);
        } catch (Exception e) {
            log.error("创建关系失败: {}", e.getMessage(), e);
            return AjaxResult.error("创建关系失败: " + e.getMessage());
        }
    }

    /**
     * 批量创建关系
     */
    @PostMapping("/relations/batch")
    @Operation(summary = "批量创建关系", description = "批量创建节点间的关系")
    public AjaxResult<?> batchCreateRelations(@RequestBody BatchCreateRelationsRequest request) {
        try {
            List<GraphRelation> relations = graphNodeService.batchCreateRelations(request);
            return AjaxResult.success(relations);
        } catch (Exception e) {
            log.error("批量创建关系失败: {}", e.getMessage(), e);
            return AjaxResult.error("批量创建关系失败: " + e.getMessage());
        }
    }

    /**
     * 获取关系
     */
    @GetMapping("/relations/{relationId}")
    @Operation(summary = "获取关系", description = "根据ID获取关系详情")
    public AjaxResult<?> getRelation(
            @Parameter(description = "关系ID") @PathVariable String relationId) {
        GraphRelation relation = graphNodeService.getRelationById(relationId);
        if (relation == null) {
            return AjaxResult.error("关系不存在: " + relationId);
        }
        return AjaxResult.success(relation);
    }

    /**
     * 获取节点的所有关系
     */
    @GetMapping("/nodes/{nodeId}/relations")
    @Operation(summary = "获取节点关系", description = "获取指定节点的所有关系")
    public AjaxResult<?> getRelationsByNode(
            @Parameter(description = "节点ID") @PathVariable String nodeId) {
        List<GraphRelation> relations = graphNodeService.getRelationsByNodeId(nodeId);
        return AjaxResult.success(relations);
    }

    /**
     * 删除关系
     */
    @DeleteMapping("/relations/{relationId}")
    @Operation(summary = "删除关系", description = "删除指定关系")
    public AjaxResult<?> deleteRelation(
            @Parameter(description = "关系ID") @PathVariable String relationId) {
        try {
            graphNodeService.deleteRelation(relationId);
            return AjaxResult.success();
        } catch (Exception e) {
            log.error("删除关系失败: relationId={}, error={}", relationId, e.getMessage(), e);
            return AjaxResult.error("删除关系失败: " + e.getMessage());
        }
    }

    // ==================== 统计操作 ====================

    /**
     * 获取文档的图统计信息
     */
    @GetMapping("/documents/{documentId}/stats")
    @Operation(summary = "获取图统计", description = "获取指定文档的节点和关系统计信息")
    public AjaxResult<?> getGraphStats(
            @Parameter(description = "文档ID") @PathVariable String documentId) {
        Map<String, Object> nodeStats = graphNodeService.getNodeStatsByDocumentId(documentId);
        Map<String, Object> relationStats = graphNodeService.getRelationStatsByDocumentId(documentId);
        
        nodeStats.put("relations", relationStats);
        return AjaxResult.success(nodeStats);
    }

    // ==================== 旧接口兼容 ====================

    /**
     * 创建关系网络（待实现）
     */
    @PostMapping("/legacy")
    @Operation(summary = "创建关系网络（旧接口）", description = "待实现")
    public AjaxResult<?> createGraph() {
        return AjaxResult.success("关系网络创建接口待实现");
    }
    
    /**
     * 获取关系网络（待实现）
     */
    @GetMapping("/legacy/{graphId}")
    @Operation(summary = "获取关系网络（旧接口）", description = "待实现")
    public AjaxResult<?> getGraph(@PathVariable String graphId) {
        return AjaxResult.success("关系网络查询接口待实现");
    }
    
    /**
     * 计算关系网络（待实现）
     */
    @PostMapping("/legacy/{graphId}/calculate")
    @Operation(summary = "计算关系网络（旧接口）", description = "待实现")
    public AjaxResult<?> calculateGraph(@PathVariable String graphId) {
        return AjaxResult.success("关系网络计算接口待实现");
    }
}
