package com.agent.management.controller;

import com.agent.management.common.Result;
import com.agent.management.model.entity.Workflow;
import com.agent.management.model.entity.WorkflowRun;
import com.agent.management.model.entity.WorkflowRunNode;
import com.agent.management.model.entity.WorkflowRunVisit;
import com.agent.management.model.vo.TagBriefVO;
import com.agent.management.repository.WorkflowRepository;
import com.agent.management.repository.WorkflowRunNodeRepository;
import com.agent.management.repository.WorkflowRunRepository;
import com.agent.management.repository.WorkflowRunVisitRepository;
import com.agent.management.service.TagService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 运行记录查询 API
 */
@RestController
@RequestMapping("/api/run-history")
@RequiredArgsConstructor
public class RunHistoryController {

    private final WorkflowRunRepository runRepo;
    private final WorkflowRunNodeRepository runNodeRepo;
    private final WorkflowRunVisitRepository runVisitRepo;
    private final WorkflowRepository workflowRepo;
    private final TagService tagService;

    /**
     * 获取所有工作流的运行记录（按工作流分组）
     */
    @GetMapping("/workflows")
    public Result<List<WorkflowWithRunsVO>> listWorkflowsWithRuns() {
        List<WorkflowRun> allRuns = runRepo.findAllByOrderByStartedAtDesc();

        // 按 workflowId 分组
        Map<Long, List<WorkflowRun>> grouped = allRuns.stream()
                .collect(Collectors.groupingBy(WorkflowRun::getWorkflowId, LinkedHashMap::new, Collectors.toList()));

        List<WorkflowWithRunsVO> result = new ArrayList<>();
        for (Map.Entry<Long, List<WorkflowRun>> entry : grouped.entrySet()) {
            Optional<Workflow> wfOpt = workflowRepo.findById(entry.getKey());
            if (wfOpt.isEmpty()) continue;

            Workflow wf = wfOpt.get();
            WorkflowWithRunsVO vo = new WorkflowWithRunsVO();
            vo.setWorkflowId(wf.getId());
            vo.setWorkflowName(wf.getName());
            vo.setDisplayName(wf.getDisplayName());
            vo.setTags(tagService.getEntityTags("workflow", String.valueOf(wf.getId())));
            vo.setRuns(entry.getValue().stream().map(this::toRunVO).collect(Collectors.toList()));
            result.add(vo);
        }
        return Result.success(result);
    }

    /**
     * 获取某次运行的详情（含节点结果）。
     *
     * <p>响应字段根据 workflow.mode 不同：</p>
     * <ul>
     *   <li>DAG 模式（默认）：返回 {@code nodes}（WorkflowRunNode 列表），{@code visits} 为空数组</li>
     *   <li>AGENTIC 模式：返回 {@code visits}（WorkflowRunVisit 列表，按 sortOrder 升序），
     *       {@code nodes} 为空数组</li>
     * </ul>
     * <p>对应设计文档 {@code docs/plans/agentic-workflow-plan.md} §3。</p>
     */
    @GetMapping("/runs/{runId}")
    public Result<RunDetailVO> getRunDetail(@PathVariable Long runId) {
        Optional<WorkflowRun> runOpt = runRepo.findById(runId);
        if (runOpt.isEmpty()) return Result.error("运行记录不存在");

        WorkflowRun run = runOpt.get();
        // 通过 workflowId 反查 mode（Workflow 是 JSON 文件存储，不在 JPA 表中）
        String mode = workflowRepo.findById(run.getWorkflowId())
                .map(Workflow::getMode)
                .orElse(null);
        boolean isAgentic = "AGENTIC".equalsIgnoreCase(mode);

        RunDetailVO detail = new RunDetailVO();
        detail.setRun(toRunVO(run));
        detail.setMode(mode);
        if (isAgentic) {
            // AGENTIC 模式：查询 Visit 链
            List<WorkflowRunVisit> visits = runVisitRepo.findByRunIdOrderBySortOrderAsc(runId);
            detail.setVisits(visits);
            detail.setNodes(Collections.emptyList());
        } else {
            // DAG 模式：保持现有契约
            List<WorkflowRunNode> nodes = runNodeRepo.findByRunIdOrderBySortOrderAsc(runId);
            detail.setNodes(nodes);
            detail.setVisits(Collections.emptyList());
        }
        return Result.success(detail);
    }

    /**
     * 删除某次运行记录（同时清理 DAG 节点记录与 AGENTIC Visit 记录）
     */
    @PostMapping("/runs/{runId}/delete")
    public Result<Void> deleteRun(@PathVariable Long runId) {
        runNodeRepo.deleteByRunId(runId);
        // AGENTIC 模式：清理 Visit 链
        List<WorkflowRunVisit> visits = runVisitRepo.findByRunIdOrderBySortOrderAsc(runId);
        if (!visits.isEmpty()) {
            runVisitRepo.deleteAll(visits);
        }
        runRepo.deleteById(runId);
        return Result.success(null);
    }

    private RunVO toRunVO(WorkflowRun run) {
        RunVO vo = new RunVO();
        vo.setId(run.getId());
        vo.setWorkflowId(run.getWorkflowId());
        vo.setRunId(run.getRunId());
        vo.setStatus(run.getStatus());
        vo.setInputs(run.getInputs());
        vo.setOutputs(run.getOutputs());
        vo.setWorkingDirFiles(run.getWorkingDirFiles());
        vo.setError(run.getError());
        vo.setStartedAt(run.getStartedAt());
        vo.setCompletedAt(run.getCompletedAt());
        vo.setVisitCount(run.getVisitCount());
        return vo;
    }

    @Data
    public static class WorkflowWithRunsVO {
        private Long workflowId;
        /** kebab-case 唯一标识（URL 用） */
        private String workflowName;
        /** 中文显示名 */
        private String displayName;
        private List<TagBriefVO> tags;
        private List<RunVO> runs;
    }

    @Data
    public static class RunVO {
        private Long id;
        private Long workflowId;
        private String runId;
        private String status;
        private String inputs;
        private String outputs;
        /** 工作空间文件列表 JSON 数组字符串（应用 .agentignore 过滤后的相对路径） */
        private String workingDirFiles;
        private String error;
        private Object startedAt;
        private Object completedAt;
        /**
         * AGENTIC 模式下的总访问次数；DAG 模式为 null。
         * 用于运行历史列表展示「N 次访问」徽标。
         */
        private Integer visitCount;
    }

    @Data
    public static class RunDetailVO {
        /** 工作流模式：DAG / AGENTIC（用于前端切换渲染逻辑） */
        private String mode;
        private RunVO run;
        /** DAG 模式：节点执行记录；AGENTIC 模式为空数组 */
        private List<WorkflowRunNode> nodes;
        /** AGENTIC 模式：访问链快照；DAG 模式为空数组 */
        private List<WorkflowRunVisit> visits;
    }
}
