package com.cmvr.test.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.test.enums.TaskStatusEnum;
import com.cmvr.test.mapper.TeNodeInstMapper;
import com.cmvr.test.model.domain.TeNodeInst;
import com.cmvr.test.model.vo.TeFlowViewVO;
import com.cmvr.test.service.ITeNodeInstService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ITeNodeInstServiceImpl extends ServiceImpl<TeNodeInstMapper, TeNodeInst> implements ITeNodeInstService {

    @Override
    public List<TeNodeInst> view(TeFlowViewVO flowViewVO) {
        LambdaQueryWrapper<TeNodeInst> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(TeNodeInst::getInstId, flowViewVO.getInstId())
                .eq(TeNodeInst::getItemId, flowViewVO.getItemId())
                .eq(StrUtil.isNotEmpty(flowViewVO.getTaskId()), TeNodeInst::getTaskId, flowViewVO.getTaskId());
        return this.list(wrapper);
    }

    @Override
    public void logRunning(String instId, String taskId, String itemId,
                           String nodeId, String nodeType,
                           String operate, String action, String paramsIn, List<Integer> iterations) {

        TeNodeInst record = new TeNodeInst();
        record.setInstId(instId);
        record.setTaskId(taskId);
        record.setItemId(itemId);
        record.setNodeId(nodeId);
        record.setNodeType(nodeType);
        record.setOperate(operate);
        record.setAction(action);
        record.setStatus(TaskStatusEnum.RUNNING.name());
        record.setParamsIn(paramsIn);
        record.setParamsOut("{}");
        record.setStartTime(System.currentTimeMillis());
        record.setIteration(getIteration(iterations));

        this.save(record);
    }

    @Override
    public void logSuccess(String instId, String itemId, String nodeId,
                           String paramsOut, String message, List<Integer> iterations) {
        LambdaUpdateWrapper<TeNodeInst> update = new LambdaUpdateWrapper<>();
        update.eq(TeNodeInst::getInstId, instId)
                .eq(TeNodeInst::getItemId, itemId)
                .eq(TeNodeInst::getNodeId, nodeId)
                .eq(TeNodeInst::getIteration, getIteration(iterations))
                .set(TeNodeInst::getParamsOut, paramsOut)
                .set(TeNodeInst::getStatus, TaskStatusEnum.SUCCESS.name())
                .set(TeNodeInst::getMessage, message)
                .set(TeNodeInst::getEndTime, System.currentTimeMillis());

        this.update(update);
    }

    @Override
    public void logFailed(String instId, String taskId, String itemId,
                          String nodeId, String nodeType,
                          String operate, String action, String params, String message, List<Integer> iterations) {

        LambdaQueryWrapper<TeNodeInst> query = Wrappers.lambdaQuery();
        query.eq(TeNodeInst::getInstId, instId)
                .eq(TeNodeInst::getItemId, itemId)
                .eq(TeNodeInst::getNodeId, nodeId)
                .eq(CollUtil.isNotEmpty(iterations), TeNodeInst::getIteration, getIteration(iterations));

        TeNodeInst existing = this.getOne(query, false);

        long now = System.currentTimeMillis();

        if (existing != null) {
            // 更新已有记录
            LambdaUpdateWrapper<TeNodeInst> update = Wrappers.lambdaUpdate();
            update.eq(TeNodeInst::getInstId, instId)
                    .eq(TeNodeInst::getItemId, itemId)
                    .eq(TeNodeInst::getNodeId, nodeId)
                    .set(TeNodeInst::getParamsOut, params)
                    .set(TeNodeInst::getStatus, TaskStatusEnum.FAILED.name())
                    .set(TeNodeInst::getMessage, message)
                    .set(TeNodeInst::getEndTime, now);

            this.update(update);
        } else {
            // 记录不存在，补插入
            TeNodeInst inst = new TeNodeInst();
            inst.setInstId(instId);
            inst.setTaskId(taskId);
            inst.setItemId(itemId);
            inst.setNodeId(nodeId);
            inst.setNodeType(nodeType);
            inst.setOperate(operate);
            inst.setAction(action);
            inst.setParamsOut(params);
            inst.setMessage(message);
            inst.setStatus(TaskStatusEnum.FAILED.name());
            inst.setStartTime(now); // 插入时设置 start 和 end
            inst.setEndTime(now);

            this.save(inst);
        }
    }

    @Override
    public void delete(String instId, String nodeId, List<Integer> iterations) {
        String iteration = getIteration(iterations);
        LambdaQueryWrapper<TeNodeInst> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(TeNodeInst::getInstId, instId)
                .eq(TeNodeInst::getNodeId, nodeId)
                .eq(TeNodeInst::getIteration, iteration);
        this.baseMapper.delete(wrapper);
    }

    @Nullable
    private static String getIteration(List<Integer> iterations) {
        return StrUtil.join(StrUtil.DASHED, iterations);
    }

    @Override
    public void update(String instId, String nodeId, TaskStatusEnum nodeStatus) {
        LambdaUpdateWrapper<TeNodeInst> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(TeNodeInst::getInstId, instId)
                .eq(TeNodeInst::getNodeId, nodeId)
                .set(TeNodeInst::getStatus, nodeStatus.name());
        this.update(wrapper);
    }
}


