package com.fs.company.service.impl;

import com.fs.common.core.domain.AjaxResult;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.company.domain.*;
import com.fs.company.mapper.*;
import com.fs.company.param.CompanyWorkflowSaveParam;
import com.fs.company.param.CompanyWorkflowUpdateBindWCParam;
import com.fs.company.service.ICompanyWorkflowService;
import com.fs.company.vo.CompanyWorkflowExportVO;
import com.fs.company.vo.CompanyWorkflowNodeVoiceVo;
import com.fs.company.vo.CompanyWorkflowVO;
import com.fs.company.vo.OptionVO;
import com.fs.enums.NodeTypeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * AI工作流Service业务层处理
 *
 * @author fs
 * @date 2026-01-06
 */
@Service
public class CompanyWorkflowServiceImpl implements ICompanyWorkflowService {

    @Autowired
    private CompanyWorkflowMapper companyWorkflowMapper;
    @Autowired
    private CompanyWorkflowNodeMapper companyWorkflowNodeMapper;
    @Autowired
    private CompanyWorkflowEdgeMapper companyWorkflowEdgeMapper;
    @Autowired
    private CompanyWorkflowNodeTypeMapper companyWorkflowNodeTypeMapper;

    private static List<String> aiCallNodeTypes = Arrays.asList("param", "ai_chat","end");
    @Override
    public CompanyWorkflowVO selectCompanyWorkflowById(Long workflowId) {
        CompanyWorkflow workflow = companyWorkflowMapper.selectCompanyWorkflowById(workflowId);
        if (workflow == null) {
            return null;
        }
        CompanyWorkflowVO vo = new CompanyWorkflowVO();
        BeanUtils.copyProperties(workflow, vo);
        vo.setNodes(companyWorkflowNodeMapper.selectCompanyWorkflowNodeByWorkflowId(workflowId));
        vo.setEdges(companyWorkflowEdgeMapper.selectCompanyWorkflowEdgeByWorkflowId(workflowId));
        return vo;
    }

    @Override
    public List<CompanyWorkflow> selectCompanyWorkflowList(CompanyWorkflow fsAiWorkflow) {
        return companyWorkflowMapper.selectCompanyWorkflowList(fsAiWorkflow);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveCompanyWorkflow(CompanyWorkflowSaveParam param) {
        Date now = DateUtils.getNowDate();
        Long workflowId = param.getWorkflowId();

        if (workflowId == null) {
            // 新增
            CompanyWorkflow workflow = new CompanyWorkflow();
            workflow.setWorkflowName(param.getWorkflowName());
            workflow.setWorkflowDesc(param.getWorkflowDesc());
            workflow.setWorkflowType(param.getWorkflowType());
            workflow.setCanvasData(param.getCanvasData());
            workflow.setStatus(1);
            workflow.setVersion(1);
            workflow.setCreateTime(now);
            workflow.setStartNodeKey(param.getStartNodeKey());
            workflow.setEndNodeKey(param.getEndNodeKey());
            workflow.setCompanyId(param.getCompanyId());
            workflow.setCompanyUserId(param.getCompanyUserId());
            companyWorkflowMapper.insertCompanyWorkflow(workflow);
            workflowId = workflow.getWorkflowId();
        } else {
            // 更新
            CompanyWorkflow workflow = new CompanyWorkflow();
            workflow.setWorkflowId(workflowId);
            workflow.setWorkflowName(param.getWorkflowName());
            workflow.setWorkflowDesc(param.getWorkflowDesc());
            workflow.setWorkflowType(param.getWorkflowType());
            workflow.setCanvasData(param.getCanvasData());
            workflow.setStartNodeKey(param.getStartNodeKey());
            workflow.setEndNodeKey(param.getEndNodeKey());
            workflow.setUpdateTime(now);
            workflow.setCompanyId(param.getCompanyId());
            workflow.setCompanyUserId(param.getCompanyUserId());
            companyWorkflowMapper.updateCompanyWorkflow(workflow);
            // 删除旧的节点和连线
            companyWorkflowNodeMapper.deleteCompanyWorkflowNodeByWorkflowId(workflowId);
            companyWorkflowEdgeMapper.deleteCompanyWorkflowEdgeByWorkflowId(workflowId);
        }

        // 保存节点
        List<CompanyWorkflowNode> nodes = param.getNodes();
        if (nodes != null && !nodes.isEmpty()) {
            for (CompanyWorkflowNode node : nodes) {
                node.setWorkflowId(workflowId);
                node.setCreateTime(now);
            }
            companyWorkflowNodeMapper.batchInsertCompanyWorkflowNode(nodes);
        }

        // 保存连线
        List<CompanyWorkflowEdge> edges = param.getEdges();
        if (edges != null && !edges.isEmpty()) {
            for (CompanyWorkflowEdge edge : edges) {
                edge.setWorkflowId(workflowId);
                edge.setCreateTime(now);
            }
            companyWorkflowEdgeMapper.batchInsertCompanyWorkflowEdge(edges);
        }

        //更新工作流后，需要删除或新增录音节点对应的id

        List<String> nodeKeyOlds = companyWorkflowMapper.selectCompanyWorkflowNodeByWorkflowId(workflowId);
        List<Long> companyUserIds = companyWorkflowMapper.selectWorkflowCompanyUserByWfId(workflowId);

        // 提取新节点的nodeKey
        List<String> newNodeKeys = nodes.stream()
                .filter(node -> aiCallNodeTypes.contains(node.getNodeType()))
                .map(CompanyWorkflowNode::getNodeKey)
                .collect(Collectors.toList());

        // 找出新增的nodeKey（新节点中有，旧节点中没有）
        List<String> nodeKeyAdd = newNodeKeys.stream()
                .filter(key -> !nodeKeyOlds.contains(key))
                .collect(Collectors.toList());

        // 找出需要删除的nodeKey（旧节点中有，新节点中没有）
        List<String> nodeKeyDel = nodeKeyOlds.stream()
                .filter(key -> !newNodeKeys.contains(key))
                .collect(Collectors.toList());
        if (!nodeKeyDel.isEmpty())companyWorkflowMapper.deleteAiWorkflowCompanyUserVoice(workflowId, nodeKeyDel);
        if (!nodeKeyAdd.isEmpty())companyWorkflowMapper.addAiWorkflowCompanyUserVoice(workflowId,companyUserIds, nodeKeyAdd);
        return workflowId;
    }

    @Override
    public int updateCompanyWorkflowStatus(Long workflowId, Integer status) {
        CompanyWorkflow workflow = new CompanyWorkflow();
        workflow.setWorkflowId(workflowId);
        workflow.setStatus(status);
        workflow.setUpdateTime(DateUtils.getNowDate());
        return companyWorkflowMapper.updateCompanyWorkflow(workflow);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteCompanyWorkflowByIds(Long[] workflowIds) {
        return companyWorkflowMapper.deleteCompanyWorkflowByIds(workflowIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long copyCompanyWorkflow(Long workflowId) {
        CompanyWorkflowVO source = selectCompanyWorkflowById(workflowId);
        if (source == null) {
            return null;
        }
        Date now = DateUtils.getNowDate();

        // 复制工作流
        CompanyWorkflow workflow = new CompanyWorkflow();
        workflow.setWorkflowName(source.getWorkflowName() + "_副本");
        workflow.setWorkflowDesc(source.getWorkflowDesc());
        workflow.setWorkflowType(source.getWorkflowType());
        workflow.setCanvasData(source.getCanvasData());
        workflow.setStatus(0);
        workflow.setVersion(1);
        workflow.setCreateTime(now);
        workflow.setStartNodeKey(source.getStartNodeKey());
        workflow.setEndNodeKey(source.getEndNodeKey());
        workflow.setCompanyId(source.getCompanyId());
        workflow.setCompanyUserId(source.getCompanyUserId());

        companyWorkflowMapper.insertCompanyWorkflow(workflow);
        Long newWorkflowId = workflow.getWorkflowId();

        // 复制节点
        List<CompanyWorkflowNode> nodes = source.getNodes();
        if (nodes != null && !nodes.isEmpty()) {
            for (CompanyWorkflowNode node : nodes) {
                node.setNodeId(null);
                node.setWorkflowId(newWorkflowId);
                node.setCreateTime(now);
            }
            companyWorkflowNodeMapper.batchInsertCompanyWorkflowNode(nodes);
        }

        // 复制连线
        List<CompanyWorkflowEdge> edges = source.getEdges();
        if (edges != null && !edges.isEmpty()) {
            for (CompanyWorkflowEdge edge : edges) {
                edge.setEdgeId(null);
                edge.setWorkflowId(newWorkflowId);
                edge.setCreateTime(now);
            }
            companyWorkflowEdgeMapper.batchInsertCompanyWorkflowEdge(edges);
        }

        return newWorkflowId;
    }

    @Override
    public List<CompanyWorkflowNodeType> selectAllEnabledNodeTypes() {
        return companyWorkflowNodeTypeMapper.selectAllEnabledNodeTypes();
    }

    @Override
    public CompanyWorkflowExportVO exportWorkflowJson(Long workflowId) {
        CompanyWorkflowVO workflowVO = selectCompanyWorkflowById(workflowId);
        if (workflowVO == null) {
            return null;
        }

        // 获取节点类型映射
//        List<CompanyWorkflowNodeType> nodeTypes = companyWorkflowNodeTypeMapper.selectAllEnabledNodeTypes();
//        Map<String, String> typeNameMap = nodeTypes.stream()
//                .collect(Collectors.toMap(CompanyWorkflowNodeType::getTypeCode, CompanyWorkflowNodeType::getTypeName));

        // 构建导出VO
        CompanyWorkflowExportVO exportVO = new CompanyWorkflowExportVO();
        exportVO.setWorkflowId(workflowVO.getWorkflowId());
        exportVO.setWorkflowName(workflowVO.getWorkflowName());
        exportVO.setWorkflowDesc(workflowVO.getWorkflowDesc());
        exportVO.setWorkflowType(workflowVO.getWorkflowType());
        exportVO.setWorkflowTypeName(getWorkflowTypeName(workflowVO.getWorkflowType()));
        exportVO.setVersion(workflowVO.getVersion());

        // 构建节点信息
        List<CompanyWorkflowNode> nodes = workflowVO.getNodes();
        Map<String, String> nodeNameMap = new HashMap<>();
        List<CompanyWorkflowExportVO.NodeInfo> nodeInfoList = new ArrayList<>();
        if (nodes != null) {
            for (CompanyWorkflowNode node : nodes) {
                nodeNameMap.put(node.getNodeKey(), node.getNodeName());
                CompanyWorkflowExportVO.NodeInfo nodeInfo = new CompanyWorkflowExportVO.NodeInfo();
                nodeInfo.setNodeKey(node.getNodeKey());
                nodeInfo.setNodeName(node.getNodeName());
                nodeInfo.setNodeType(NodeTypeEnum.fromCode(node.getNodeType()).getValue());
                nodeInfo.setNodeTypeName(NodeTypeEnum.fromCode(node.getNodeType()).getDescription());
                nodeInfo.setNodeConfig(node.getNodeConfig());
                nodeInfo.setPosX(node.getPosX());
                nodeInfo.setPosY(node.getPosY());
                nodeInfo.setSortOrder(node.getSortOrder());
                nodeInfoList.add(nodeInfo);
            }
        }
        exportVO.setNodes(nodeInfoList);

        // 构建连接信息(按sortOrder排序)
        List<CompanyWorkflowEdge> edges = workflowVO.getEdges();
        List<CompanyWorkflowExportVO.EdgeInfo> edgeInfoList = new ArrayList<>();
        if (edges != null) {
            edges.sort(Comparator.comparing(e -> e.getSortOrder() != null ? e.getSortOrder() : 0));
            for (CompanyWorkflowEdge edge : edges) {
                CompanyWorkflowExportVO.EdgeInfo edgeInfo = new CompanyWorkflowExportVO.EdgeInfo();
                edgeInfo.setEdgeKey(edge.getEdgeKey());
                edgeInfo.setEdgeLabel(edge.getEdgeLabel());
                edgeInfo.setSourceNodeKey(edge.getSourceNodeKey());
                edgeInfo.setSourceNodeName(nodeNameMap.get(edge.getSourceNodeKey()));
                edgeInfo.setTargetNodeKey(edge.getTargetNodeKey());
                edgeInfo.setTargetNodeName(nodeNameMap.get(edge.getTargetNodeKey()));
                edgeInfo.setConditionExpr(edge.getConditionExpr());
                edgeInfo.setSortOrder(edge.getSortOrder());
                edgeInfoList.add(edgeInfo);
            }
        }
        exportVO.setEdges(edgeInfoList);

        return exportVO;
    }

    @Override
    public List<CompanyUser> listCompanyUser() {
        return SpringUtils.getBean(CompanyUserMapper.class).selectAllCompanyUserList();
    }

    private String getWorkflowTypeName(Integer workflowType) {
        if (workflowType == null) return "";
        switch (workflowType) {
            case 1: return "对话流程";
            case 2: return "任务流程";
            case 3: return "审批流程";
            default: return "";
        }
    }

    @Override
    public List<CompanyWorkflowNode> selectWorkflowNodesByCompanyUserId(Long companyUserId, List<String> nodeTypes) {
        // 根据企业用户ID查询工作流
        List<CompanyWorkflow> workflows = companyWorkflowMapper.selectCompanyWorkflowByCompanyUserId(companyUserId);
        if (workflows == null || workflows.isEmpty()) {
            return new ArrayList<>();
        }

        // 收集所有工作流的指定类型节点
        List<CompanyWorkflowNode> result = new ArrayList<>();
        for (CompanyWorkflow workflow : workflows) {
            List<CompanyWorkflowNode> nodes = companyWorkflowNodeMapper.selectNodesByWorkflowIdAndTypes(
                    workflow.getWorkflowId(), nodeTypes);
            if (nodes != null) {
                result.addAll(nodes);
            }
        }
        return result;
    }

    @Override
    public int updateNodeVoiceUrl(Long nodeId, String voiceUrl, Long companyUserId) {
        // 1. 查询节点是否存在
        CompanyWorkflowNode node = companyWorkflowNodeMapper.selectCompanyWorkflowNodeById(nodeId);
        if (node == null) {
            return -1; // 节点不存在
        }

        // 2. 查询节点所属的工作流
        CompanyWorkflow workflow = companyWorkflowMapper.selectCompanyWorkflowById(node.getWorkflowId());
        if (workflow == null) {
            return -1; // 工作流不存在
        }

        // 3. 校验工作流是否属于该企业用户
        if (workflow.getCompanyUserId() == null || !workflow.getCompanyUserId().equals(companyUserId)) {
            return -2; // 无权限
        }

        // 4. 更新voiceUrl
        CompanyWorkflowNode updateNode = new CompanyWorkflowNode();
        updateNode.setNodeId(nodeId);
        updateNode.setVoiceUrl(voiceUrl);
        return companyWorkflowNodeMapper.updateCompanyWorkflowNode(updateNode);
    }

    @Override
    public CompanyUser getCompanyUserById(Long id) {
        return SpringUtils.getBean(CompanyUserMapper.class).selectCompanyUserById( id);
    }

    @Override
    public Boolean checkCompanyUserBeUsed(Long companyUserId) {
        return companyWorkflowMapper.selectCompanyWorkflowCountByCompanyUserId(companyUserId) > 0;
    }

    @Override
    public AjaxResult updateWorkflowBindCompanyUser(CompanyWorkflowUpdateBindWCParam param) {
        if (param == null ||param.getWorkflowId() == null || param.getCompanyUserIds() == null || param.getCompanyUserIds().size() == 0) return AjaxResult.error("传参异常");
        CompanyWorkflow fsAiWorkflowResult = companyWorkflowMapper.selectCompanyWorkflowById(Long.valueOf(param.getWorkflowId().toString()));
        if (fsAiWorkflowResult == null)return AjaxResult.error("未查询到对应工作流，请刷新后重试");
        int i = companyWorkflowMapper.insertCompanyWorkflowCompanyUser(param.getWorkflowId(),param.getCompanyUserIds());
        List<CompanyWorkflowNode> fsAiWorkflowNodes = companyWorkflowNodeMapper.selectNodesByWorkflowIdAndTypes(param.getWorkflowId(), aiCallNodeTypes);
        companyWorkflowMapper.insertAiWorkflowCompanyUserVoice(param.getWorkflowId(), param.getCompanyUserIds(), fsAiWorkflowNodes);
        return AjaxResult.success("绑定成功");
    }

    @Override
    public AjaxResult getBindCompanyUserByWorkflowId(Long workflowId) {
        CompanyWorkflow fsAiWorkflow = companyWorkflowMapper.selectCompanyWorkflowById(workflowId);
        if (fsAiWorkflow == null) return AjaxResult.error("工作流不存在");
        return AjaxResult.success(companyWorkflowMapper.getBindCompanyUserByWorkflowId(workflowId));
    }

    @Override
    public List<CompanyWorkflowNodeVoiceVo> getMyWorkflowNodes(Long companyUserId) {
        return companyWorkflowMapper.getMyWorkflowNodes(companyUserId);
    }

    @Override
    public List<OptionVO> optionList(Long companyId) {
        return companyWorkflowMapper.optionList(companyId);
    }
}
