package cd.casic.ci.process.process.service.template.impl;


import cd.casic.ci.process.dto.req.template.TemplateCreateByDataReq;
import cd.casic.ci.process.dto.req.template.TemplateCreateReq;
import cd.casic.ci.process.dto.req.template.TemplateQueryReq;
import cd.casic.ci.process.dto.req.template.TemplateUpdateReq;
import cd.casic.ci.process.dto.resp.template.TemplateFindResp;
import cd.casic.ci.process.dto.resp.template.TemplateStageResp;
import cd.casic.ci.process.process.converter.TemplateConverter;
import cd.casic.ci.process.process.converter.TemplateStageConverter;
import cd.casic.ci.process.process.converter.TemplateTaskConverter;
import cd.casic.ci.process.process.dao.template.TemplateManagerDao;
import cd.casic.ci.process.process.dao.template.TemplateStageDao;
import cd.casic.ci.process.process.dao.template.TemplateTaskDao;
import cd.casic.ci.process.process.dataObject.template.TemplateManager;
import cd.casic.ci.process.process.dataObject.template.TemplateStage;
import cd.casic.ci.process.process.dataObject.template.TemplateTask;
import cd.casic.ci.process.process.service.template.TemplateManagerService;
import cd.casic.ci.process.process.service.template.TemplateStageService;
import cd.casic.ci.process.util.snowflake.SnowflakeIdentifierGenerator;
import cd.casic.framework.commons.exception.ServiceException;
import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants;
import cd.casic.framework.commons.pojo.PageResult;
import cd.casic.framework.security.dal.user.AdminUserDO;
import cd.casic.framework.tenant.core.service.AdminUserServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author HopeLi
 * @version v1.0
 * @ClassName PipelineServiceImpl
 * @Date: 2025/5/13 10:31
 * @Description:
 */
@Service
@Slf4j
public class TemplateManagerServiceImpl extends ServiceImpl<TemplateManagerDao, TemplateManager> implements TemplateManagerService {

    @Resource
    private TemplateManagerDao templateManagerDao;

    @Resource
    private TemplateStageDao templateStageDao;

    @Resource
    private TemplateTaskDao templateTaskDao;

    @Resource
    private AdminUserServiceImpl adminUserService;
    @Resource
    private TemplateConverter templateConverter;
    @Resource
    private TemplateStageService templateStageService;
    @Resource
    private SnowflakeIdentifierGenerator idWork;
    @Resource
    private TemplateStageConverter templateStageConverter;

    public String createTemplateManager(TemplateCreateReq req){
        TemplateManager templateManager = templateConverter.managerCreateReqToManager(req);
        save(templateManager);
        String templateManagerId = templateManager.getId();
        // 创建模板节点
        TemplateStage firstStage = new TemplateStage();
        firstStage.setTemplateId(templateManagerId);
        firstStage.setStageName("源码阶段");
        firstStage.setParentId("-1");
        firstStage.setStageSort(1);
        String firstStageId = idWork.nextUUID(null);
        firstStage.setId(firstStageId);
        TemplateStage secondStage = new TemplateStage();
        secondStage.setTemplateId(templateManagerId);
        secondStage.setStageName("源码阶段");
        secondStage.setStageSort(1);
        secondStage.setParentId(firstStageId);
        String secondStageId = idWork.nextUUID(null);
        secondStage.setId(secondStageId);
        TemplateTask task = new TemplateTask();
        task.setTemplateId(templateManagerId);
        task.setStageId(secondStageId);
        task.setTaskSort(1);
        task.setTaskName("初始节点");
        task.setTemplateId(templateManagerId);
        task.setTaskType(req.getTemplateType());
        templateStageDao.insert(firstStage);
        templateStageDao.insert(secondStage);
        templateTaskDao.insert(task);
        return templateManagerId;
    }
    public String updateTemplateManager(TemplateUpdateReq req){
        TemplateManager templateManager = templateConverter.managerUpdateReqToManager(req);
        updateById(templateManager);
        String templateManagerId = templateManager.getId();
        return templateManagerId;
    }
    @Override
    public PageResult<TemplateFindResp> findTemplatePage(TemplateQueryReq query) {

        QueryWrapper<TemplateManager> wrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(query.getId())){
            wrapper.eq("id",query.getId());
        }
        if (!ObjectUtils.isEmpty(query.getIdList())){
            wrapper.in("id",query.getId());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateName())){
            wrapper.like("template_name",query.getTemplateName());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateType())){
            wrapper.eq("template_type",query.getTemplateType());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateCode())){
            wrapper.eq("template_code",query.getTemplateCode());
        }
        if (!ObjectUtils.isEmpty(query.getCreator())){
            wrapper.eq("creator",query.getCreator());
        }

        Page<TemplateManager> templateManagerPage = templateManagerDao.selectPage(new Page<>(query.getPageNo(), query.getPageSize()), wrapper);

        if (ObjectUtils.isEmpty(templateManagerPage)){
            return new PageResult<>();
        }

        List<TemplateFindResp> respList = TemplateConverter.INSTANCE.toRespList(templateManagerPage.getRecords());

        //对流水线模板进行流水线信息赋值
        respList.forEach(this::setStageAndTask);
        respList.forEach(this::setUserName);

        return new PageResult<>(respList,templateManagerPage.getTotal(),templateManagerPage.getCurrent(),templateManagerPage.getSize());
    }

    @Override
    public List<TemplateFindResp> findTemplateList(TemplateQueryReq query) {
        QueryWrapper<TemplateManager> wrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(query.getId())){
            wrapper.eq("id",query.getId());
        }
        if (!ObjectUtils.isEmpty(query.getIdList())){
            wrapper.in("id",query.getId());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateName())){
            wrapper.like("template_name",query.getTemplateName());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateType())){
            wrapper.eq("template_type",query.getTemplateType());
        }
        if (!ObjectUtils.isEmpty(query.getTemplateCode())){
            wrapper.eq("template_code",query.getTemplateCode());
        }
        if (!ObjectUtils.isEmpty(query.getCreator())){
            wrapper.eq("creator",query.getCreator());
        }

        Page<TemplateManager> templateManagerPage = templateManagerDao.selectPage(new Page<>(query.getPageNo(), query.getPageSize()), wrapper);

        if (ObjectUtils.isEmpty(templateManagerPage)){
            return new ArrayList<>();
        }

        List<TemplateFindResp> respList = TemplateConverter.INSTANCE.toRespList(templateManagerPage.getRecords());

        //对流水线模板进行流水线信息赋值
        respList.forEach(this::setStageAndTask);
        respList.forEach(this::setUserName);
        return respList;
    }

    @Override
    public TemplateFindResp findTemplateById(String id) {
        TemplateManager templateManager = templateManagerDao.selectById(id);
        TemplateFindResp resp = TemplateConverter.INSTANCE.toResp(templateManager);
        setStageAndTask(resp);
        setUserName(resp);
        return resp;
    }

    @Override
    public String createTemplateByData(TemplateCreateByDataReq req) {
        TemplateManager templateManager = templateConverter.managerDataToManagerModule(req);
        templateManager.setId(idWork.nextUUID(null));
        templateManagerDao.insert(templateManager);

        List<TemplateStage> stageList = new ArrayList<>();
        List<TemplateTask> taskList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(req.getStageCreateByDataReqList())){
            req.getStageCreateByDataReqList().forEach(o->{
                TemplateStage templateStage = templateStageConverter.stageDataToStageModule(o);
                templateStage.setId(idWork.nextUUID(null));
                templateStage.setTemplateId(templateManager.getId());
                templateStage.setParentId("-1");
                stageList.add(templateStage);

                if (!ObjectUtils.isEmpty(o.getStageCreateByDataReqList())){
                    o.getStageCreateByDataReqList().forEach(j->{
                        TemplateStage childTemplateStage = templateStageConverter.stageDataToStageModule(j);
                        childTemplateStage.setId(idWork.nextUUID(null));
                        childTemplateStage.setParentId(templateStage.getId());
                        childTemplateStage.setTemplateId(templateStage.getTemplateId());
                        stageList.add(childTemplateStage);

                        if (!ObjectUtils.isEmpty(j.getTaskCreateByDataReqList())){
                            j.getTaskCreateByDataReqList().forEach(k->{
                                TemplateTask templateTask = TemplateTaskConverter.INSTANCE.taskDataToTaskModule(k);
                                templateTask.setId(idWork.nextUUID(null));
                                templateTask.setStageId(childTemplateStage.getId());
                                templateTask.setTemplateId(templateManager.getId());
                                taskList.add(templateTask);
                            });
                        }
                    });
                }
            });
        }
        templateStageDao.insertBatch(stageList);
        templateTaskDao.insertBatch(taskList);
        return templateManager.getId();
    }

    private void setUserName(TemplateFindResp templateFindResp) {
        if (!StringUtils.isEmpty(templateFindResp.getCreator())){
            AdminUserDO user = adminUserService.getUser(Long.valueOf(templateFindResp.getCreator()));
            if (!ObjectUtils.isEmpty(user)){
                templateFindResp.setCreatorName(user.getUsername());
            }
        }

        if (!StringUtils.isEmpty(templateFindResp.getUpdater())){
            AdminUserDO user = adminUserService.getUser(Long.valueOf(templateFindResp.getUpdater()));
            if (!ObjectUtils.isEmpty(user)){
                templateFindResp.setUpdaterName(user.getUsername());
            }
        }
    }





    private void setStageAndTask(TemplateFindResp o) {
        //拼接流水线模板主节点
        List<TemplateStageResp> allStagesTask = templateStageService.findAllStagesTask(o.getId());
        o.setStageList(allStagesTask);
    }

    private List<TemplateStage> findSecondStageAndTask(String stagesId) {
        List<TemplateStage> otherStage = findSecondStage(stagesId);
        List<TemplateStage> list = new ArrayList<>();
        List<String> stageIdList = otherStage.stream().map(TemplateStage::getId).toList();
        if (stageIdList.isEmpty()) {
            throw new ServiceException(GlobalErrorCodeConstants.PIPELINE_ERROR.getCode(),"当前阶段下不存在节点");
        }
        Map<String, List<TemplateTask>> stageIdTaskMap = getTaskByStageIdList(stageIdList).stream().collect(Collectors.groupingBy(TemplateTask::getStageId));
        for (TemplateStage stage : otherStage) {
            //获取阶段配置及任务
            String otherId = stage.getId();
            List<TemplateTask> allStageTask = stageIdTaskMap.get(otherId);
            allStageTask.sort(Comparator.comparing(TemplateTask::getTaskSort));
            stage.setTaskValues(allStageTask);
            list.add(stage);
        }
        return list;
    }

    private List<TemplateTask> getTaskByStageIdList(List<String> stageIdList) {
        LambdaQueryWrapper<TemplateTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(TemplateTask::getStageId,stageIdList);
        return templateTaskDao.selectList(wrapper);
    }

    private List<TemplateStage> findSecondStage(String stagesId) {
        LambdaQueryWrapper<TemplateStage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TemplateStage::getParentId,stagesId);
        return templateStageDao.selectList(wrapper);
    }

    private List<TemplateStage> findAllMainStage(String id) {
        LambdaQueryWrapper<TemplateStage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TemplateStage::getTemplateId,id);
        wrapper.eq(TemplateStage::getParentId,"-1");
        return templateStageDao.selectList(wrapper);
    }
}
