package cn.iocoder.yudao.module.mes.service.moldticketresults;

import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.common.controller.admin.moldticketresults.enums.MoldJobResultEnum;
import cn.iocoder.yudao.module.common.dal.dataobject.moldticketmanagement.MoldTicketManagementDO;
import cn.iocoder.yudao.module.common.dal.mysql.moldticketmanagement.MoldTicketManagementMapper;
import cn.iocoder.yudao.module.mes.service.moldticketresults.MoldTicketResultsService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.common.controller.admin.moldticketresults.vo.*;
import cn.iocoder.yudao.module.common.dal.dataobject.moldticketresults.MoldTicketResultsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.common.dal.mysql.moldticketresults.MoldTicketResultsMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;

/**
 * 工单检验结果 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class MoldTicketResultsServiceImpl implements MoldTicketResultsService {

    @Resource
    private MoldTicketResultsMapper moldticketResultsMapper;

    @Resource
    @Lazy
    private MoldTicketManagementMapper moldticketManagementMapper;


    @Override
    public Long createMoldTicketResults(MoldTicketResultsSaveReqVO createReqVO) {
        // 插入
        MoldTicketResultsDO moldticketResults = BeanUtils.toBean(createReqVO, MoldTicketResultsDO.class);
        moldticketResultsMapper.insert(moldticketResults);
        // 返回
        return moldticketResults.getId();
    }

    @Override
    public void updateMoldTicketResults(MoldTicketResultsSaveReqVO updateReqVO) {
        // 校验存在
        validateMoldTicketResultsExists(updateReqVO.getId());
        // 更新
        MoldTicketResultsDO updateObj = BeanUtils.toBean(updateReqVO, MoldTicketResultsDO.class);
        moldticketResultsMapper.updateById(updateObj);
    }

    @Override
    public void deleteMoldTicketResults(Long id) {
        // 校验存在
        validateMoldTicketResultsExists(id);
        // 删除
        moldticketResultsMapper.deleteById(id);
    }

    private void validateMoldTicketResultsExists(Long id) {
        if (moldticketResultsMapper.selectById(id) == null) {
            throw exception(TICKET_RESULTS_NOT_EXISTS);
        }
    }

    @Override
    public MoldTicketResultsDO getMoldTicketResults(Long id) {
        return moldticketResultsMapper.selectById(id);
    }

    @Override
    public PageResult<MoldTicketResultsDO> getMoldTicketResultsPage(MoldTicketResultsPageReqVO pageReqVO) {
        return moldticketResultsMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateMoldTicketResults(List<MoldTicketResultsSaveReqVO> updateReqVOList) {
        if (CollectionUtils.isEmpty(updateReqVOList)) {
            return;
        }

        // 1. 数据验证
        validateBatchUpdateData(updateReqVOList);

        // 2. 批量更新
        List<MoldTicketResultsDO> updateList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();

        for (MoldTicketResultsSaveReqVO vo : updateReqVOList) {
            // 转换为DO
            MoldTicketResultsDO updateDO = BeanUtils.toBean(vo, MoldTicketResultsDO.class);
            updateDO.setUpdateTime(now);
            updateList.add(updateDO);
        }

        // 3. 执行批量更新
        moldticketResultsMapper.updateBatch(updateList);

        //4. 判断是否全部已检验
        handleInspectionResult(updateReqVOList);


    }

    /**
     * 验证批量更新数据
     */
    private void validateBatchUpdateData(List<MoldTicketResultsSaveReqVO> updateReqVOList) {
        if (CollectionUtils.isEmpty(updateReqVOList)) {
            return;
        }

        Set<Long> idSet = new HashSet<>();

        for (int i = 0; i < updateReqVOList.size(); i++) {
            MoldTicketResultsSaveReqVO vo = updateReqVOList.get(i);

            // 验证ID不能为空
            if (vo.getId() == null) {
                throw exception(TICKET_RESULTS_ID_NOT_NULL);
            }

            idSet.add(vo.getId());

            // 调用单个验证逻辑
            validateMoldTicketResultsExists(vo.getId());
        }
    }


    /**
     * 处理检验结果
     */
    private void handleInspectionResult(List<MoldTicketResultsSaveReqVO> updateReqVOList) {
        if (CollectionUtils.isEmpty(updateReqVOList)) {
            return;
        }

        // 检查是否有未填写的
        boolean hasPending = updateReqVOList.stream()
                .anyMatch(vo -> vo.getInspectionResult() == null || vo.getInspectionResult().equals(MoldJobResultEnum.PENDING.getCode()));

        if (hasPending) {
            return;
        }
        MoldTicketManagementDO moldticketManagementDO = moldticketManagementMapper.selectById(updateReqVOList.get(0).getManagementId());
        if (moldticketManagementDO == null ){
            throw exception(TICKET_MANAGEMENT_NOT_EXISTS);
        }
        moldticketManagementDO.setTaskTime(LocalDateTime.now());
        //设置为已完成
        moldticketManagementDO.setJobStatus(1);
        // 检查是否有不通过的
        boolean hasFail = updateReqVOList.stream()
                .anyMatch(vo -> vo.getInspectionResult() != null && vo.getInspectionResult().equals(MoldJobResultEnum.FAIL.getCode()));
        if (hasFail) {
            moldticketManagementDO.setJobResult(MoldJobResultEnum.FAIL.getCode());

        } else {
            moldticketManagementDO.setJobResult(MoldJobResultEnum.PASS.getCode());
        }
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        moldticketManagementDO.setOperator(String.valueOf(loginUser.getId()));

        moldticketManagementMapper.updateById(moldticketManagementDO);

    }

}