package net.ferrum.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.ferrum.business.domain.bo.QsProjectAttributesBo;
import net.ferrum.business.domain.vo.QsProjectAttributesVo;
import net.ferrum.business.service.IQsProjectAttributesService;
import net.ferrum.common.constant.UserConstants;
import net.ferrum.common.utils.BeanCopyUtils;
import net.ferrum.common.utils.StringUtils;
import net.ferrum.common.core.page.TableDataInfo;
import net.ferrum.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import net.ferrum.business.domain.bo.QsProjectsBo;
import net.ferrum.business.domain.vo.QsProjectsVo;
import net.ferrum.business.domain.QsProjects;
import net.ferrum.business.mapper.QsProjectsMapper;
import net.ferrum.business.service.IQsProjectsService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLongArray;

/**
 * 项目管理Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-19
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class QsProjectsServiceImpl implements IQsProjectsService {

    private final QsProjectsMapper baseMapper;
    private final IQsProjectAttributesService iQsProjectAttributesService;
    private final PlatformTransactionManager transactionManager;

    private final StringBuilder failureMsg = new StringBuilder();

    /**
     * 查询项目管理
     */
    @Override
    public QsProjectsVo queryById(Long projectId){
        return baseMapper.selectVoById(projectId);
    }

    public QsProjects selectById(Long projectId){
        QsProjects entity = new QsProjects();
        QsProjectsVo vo = baseMapper.selectVoById(projectId);
        BeanCopyUtils.copy(vo,entity);
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(1);
        pageQuery.setPageSize(10);
        TableDataInfo<QsProjects> data = queryPageList(entity,pageQuery);
        if ( !data.getRows().isEmpty() ){
            return data.getRows().get(0);
        }
        else{
            return null;
        }

    }

    /**
     * 查询项目管理列表
     */
    @Override
    public TableDataInfo<QsProjects> queryPageList(QsProjects entity, PageQuery pageQuery) {
        Wrapper<QsProjects> lqw = buildQueryWrapper(entity);
        Page<QsProjects> result = baseMapper.selectPageQsProjectsList(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询项目管理列表
     */
    @Override
    public List<QsProjectsVo> queryList(QsProjectsBo bo) {
        QsProjects entity = new QsProjects();
        BeanCopyUtils.copy(bo,entity);
        Wrapper<QsProjects> lqw = buildQueryWrapper(entity);
        return baseMapper.selectVoList(lqw);
    }

    private QueryWrapper<QsProjects> buildQueryWrapper(QsProjects bo) {
        Map<String, Object> params = bo.getParams();
        //LambdaQueryWrapper<QsProjectsBo> lqw = Wrappers.lambdaQuery();
        QueryWrapper<QsProjects> lqw = new QueryWrapper<>();
        lqw.eq("a.del_flag", UserConstants.NORMAL);

        lqw.eq(bo.getBatchId() != null, "a.batch_id", bo.getBatchId());
        lqw.like(StringUtils.isNotBlank(bo.getBatchName()), "b.batch_name", bo.getBatchName());
        lqw.like(StringUtils.isNotBlank(bo.getProjectName()), "a.project_name", bo.getProjectName());
        lqw.like(bo.getStageDisplayName() != null, "ms.display_name", bo.getStageDisplayName());
        lqw.like(StringUtils.isNotBlank(bo.getProjectCompletion()), "a.project_completion", bo.getProjectCompletion());
        lqw.between(params.get("beginStartDate") != null && params.get("endStartDate") != null,
            "a.start_date" ,params.get("beginStartDate"), params.get("endStartDate"));
        lqw.between(params.get("beginEndTime") != null && params.get("endEndTime") != null,
            "a.end_time" ,params.get("beginEndTime"), params.get("endEndTime"));
        return lqw;
    }

    /**
     * 新增项目管理
     */
    @Override
    public Boolean insertByBo(QsProjectsBo bo) {

        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        boolean updateSuccess = true;
        transactionTemplate.execute(status -> {
        try {
            // 在这里执行数据库操作，这些操作将在同一个事务中执行
            QsProjects add = BeanUtil.toBean(bo, QsProjects.class);
            //validEntityBeforeSave(add);
            boolean flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setProjectId(add.getProjectId());
                //插入项目所有的规格参数
                bo.getSpecInfoList().forEach(specValue -> {
                    QsProjectAttributesBo specInfoBo = new QsProjectAttributesBo();
                    BeanCopyUtils.copy(specValue,specInfoBo);
                    specInfoBo.setProjectId(bo.getProjectId());
                    if (! iQsProjectAttributesService.insertByBo(specInfoBo)) {
                        String msg = "插入异常——在插入项目规格信息时出现异常！" + "参数：" + specInfoBo;
                        failureMsg.append(msg);
                        log.error(msg);
                        throw new RuntimeException(msg);
                    }
                });
                //在 qs_project_stage_status 表中插入当前项目的阶段的子并行阶段
                // 在项目表中插入项目时，默认项目当前阶段为1，第一阶段：项目建议，没有并行的子阶段，所以不用做这步操作
            }
            else{
                String msg = "插入异常——在插入项目主体信息时出现异常！" + "参数：" + bo;
                failureMsg.append(msg);
                log.error(msg);
                throw new RuntimeException(msg);
            }
            // 如果一切正常，返回null表示提交事务
            return null;
        } catch (Exception e) {
            // 如果发生异常，可以手动回滚事务
            status.setRollbackOnly();
            throw e;
        }
        });

        return updateSuccess;

    }

    /**
     * 修改项目管理
     */
    @Override
    public Boolean updateByBo(QsProjectsBo bo) {

        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        boolean updateSuccess = true;
        transactionTemplate.execute(status -> {
            try {
                // 在这里执行数据库操作，这些操作将在同一个事务中执行
                QsProjectAttributesBo querySpecInfoBo = new QsProjectAttributesBo();
                querySpecInfoBo.setProjectId(bo.getProjectId());
                List<QsProjectAttributesVo> projSepcValueList =iQsProjectAttributesService.queryList(querySpecInfoBo);

                // 将 projSepcValueList 的 id 存入 Map
                Map<Long, QsProjectAttributesVo> mapB = new HashMap<>();
                for (QsProjectAttributesVo item : projSepcValueList) {
                    mapB.put(item.getId(), item);
                }

                bo.getSpecInfoList().forEach(specValue -> {
                    QsProjectAttributesVo oldSpecInfo = mapB.get(specValue.getId());

                    QsProjectAttributesBo specInfoBo = new QsProjectAttributesBo();

                    if (oldSpecInfo == null){  //没有这个规格属性，就插入一个新的
                        BeanCopyUtils.copy(specValue,specInfoBo);
                        specInfoBo.setProjectId(bo.getProjectId());
                        if (! iQsProjectAttributesService.insertByBo(specInfoBo)) {
                            String msg = "修改项目，插入异常——在插入项目规格信息时出现异常！" + "参数：" + specInfoBo;
                            failureMsg.append(msg);
                            log.error(msg);
                            throw new RuntimeException(msg);
                        }
                    }
                    else if (oldSpecInfo.getId().equals(specValue.getId())  &&
                        !oldSpecInfo.getValue().equals(specValue.getValue())){ //规格发生改变
                        BeanCopyUtils.copy(specValue,specInfoBo);
                        specInfoBo.setProjectId(bo.getProjectId());
                        if (! iQsProjectAttributesService.updateByBo(specInfoBo)) {
                            String msg = "修改项目，更新异常——在更新项目规格信息时出现异常！" + "参数：" + specInfoBo;
                            failureMsg.append(msg);
                            log.error(msg);
                            throw new RuntimeException(msg);
                        }
                    }
                });

                QsProjects update = BeanUtil.toBean(bo, QsProjects.class);
                validEntityBeforeSave(update);
                if (!(baseMapper.updateById(update) > 0)){
                    String msg = "修改项目，更新异常——在更新项目信息时出现异常！" + "参数：" + update.toString();
                    failureMsg.append(msg);
                    log.error(msg);
                    throw new RuntimeException(msg);
                }

                // 如果一切正常，返回null表示提交事务
                return null;
            } catch (Exception e) {
                // 如果发生异常，可以手动回滚事务
                status.setRollbackOnly();
                throw e;
            }
        });

        return updateSuccess;
     }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(QsProjects entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除项目管理
     */
    @Override
    public String deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {

        List <QsProjects> qsProjectList = baseMapper.selectBatchIds(ids);

        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
            failureMsg.setLength(0); // 清空内容
            for (int i = 0; i < qsProjectList.size(); i++) {
                QsProjects qsProject = qsProjectList.get(i);
                if (qsProject.getCurrentMasterStageId() > UserConstants.PROJECT_START_ID) { // 项目已经开工，不允许删除
                    String msg = "删除项目，项目名称：" + qsProject.getProjectName() +
                        "已经开工，不能删除！";
                    failureMsg.append(msg);
                }
            }
            if (failureMsg.length()>0) return failureMsg.toString();
        }

        failureMsg.setLength(0); // 清空内容
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        AtomicLongArray noDelProject = new AtomicLongArray(ids.size());
        String sRet = transactionTemplate.execute(status -> {
            try {
                // 在这里执行数据库操作，这些操作将在同一个事务中执行
                ids.forEach(projectId -> {
                    QsProjects qsProject = baseMapper.selectById(projectId);
                    if(qsProject == null){return;}
                    //删除 项目的规格参数
                    if(!iQsProjectAttributesService.deleteByProjectId(projectId)){
                        String msg = "删除项目，删除异常——在删除项目规格信息时出现异常！" + "参数：" + qsProject;
                        failureMsg.append(msg);
                        log.error(msg);
                        throw new RuntimeException(msg);
                    }
                    //删除 项目基本信息
                    if(!( baseMapper.deleteById(projectId) > 0)){
                        String msg = "删除项目，删除异常——在删除项目规格信息时出现异常！" + "参数：" + qsProject;
                        failureMsg.append(msg);
                        log.error(msg);
                        throw new RuntimeException(msg);
                    }
                });
                // 如果一切正常，返回null表示提交事务
                return failureMsg.toString();
            } catch (Exception e) {
                // 如果发生异常，可以手动回滚事务
                status.setRollbackOnly();
                return failureMsg.toString();
            }
        });
        return sRet;
    }

    /**
     * 校验项目是否已经开工
     *
     * @param projectId 项目ID
     * @return 结果
     */
    @Override
    public boolean checkProjectInProcessing(Long projectId) {
        return baseMapper.exists(new LambdaQueryWrapper<QsProjects>()
                .gt(QsProjects::getCurrentMasterStageId, UserConstants.PROJECT_START_ID)
                .eq(ObjectUtil.isNotNull(projectId), QsProjects::getProjectId, projectId)
                );
    }
}
