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

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.erp.service.mold.MoldService;
import cn.iocoder.yudao.module.mes.controller.admin.moldrecord.vo.MoldRecordPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.moldrecord.vo.MoldRecordRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.moldrecord.vo.MoldRecordSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.machine.MachineComponentDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.moldrecord.MoldRecordDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.moldrecord.MoldRecordSubjectDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO;
import cn.iocoder.yudao.module.mes.dal.mysql.moldrecord.MoldRecordMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.moldrecord.MoldRecordSubjectDetailMapper;
import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO;
import cn.iocoder.yudao.module.mes.service.machine.MachineComponentService;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MOLD_RECORD_NOT_EXISTS;

/**
 * 模具维保 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class MoldRecordServiceImpl implements MoldRecordService {

    @Resource
    private MoldRecordMapper moldRecordMapper;
    @Resource
    private MoldRecordSubjectDetailMapper moldRecordSubjectDetailMapper;
    @Resource
    private MesNoRedisDAO noRedisDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createMoldRecord(MoldRecordSaveReqVO createReqVO) {
        // 插入
        MoldRecordDO moldRecord = BeanUtils.toBean(createReqVO, MoldRecordDO.class);
        moldRecord.setRecordStatus("草稿");
        if (StringUtils.isEmpty(moldRecord.getCode())) {
            String no = noRedisDAO.generate3(MesNoRedisDAO.MOLD_RECORD_NO_PREFIX);
            moldRecord.setCode(no);
        }
        moldRecordMapper.insert(moldRecord);

        // 插入子表
        if(createReqVO.getMoldRecordSubjectDetails()!=null && createReqVO.getMoldRecordSubjectDetails().size()>0)
            createMoldRecordSubjectDetailList(moldRecord.getId(), createReqVO.getMoldRecordSubjectDetails());
        // 返回
        return moldRecord.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMoldRecord(MoldRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateMoldRecordExists(updateReqVO.getId());
        // 更新
        MoldRecordDO updateObj = BeanUtils.toBean(updateReqVO, MoldRecordDO.class);
        moldRecordMapper.updateById(updateObj);

        // 更新子表
        updateMoldRecordSubjectDetailList(updateReqVO.getId(), updateReqVO.getMoldRecordSubjectDetails());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMoldRecord(Long id) {
        // 校验存在
        validateMoldRecordExists(id);
        // 删除
        moldRecordMapper.deleteById(id);

        // 删除子表
        deleteMoldRecordSubjectDetailByRecordId(id);
    }

    private void validateMoldRecordExists(Long id) {
        if (moldRecordMapper.selectById(id) == null) {
            throw exception(MOLD_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public MoldRecordDO getMoldRecord(Long id) {
        return moldRecordMapper.selectById(id);
    }

    @Override
    public PageResult<MoldRecordDO> getMoldRecordPage(MoldRecordPageReqVO pageReqVO) {
        return moldRecordMapper.selectPage(pageReqVO);
    }
    @Resource
    private AdminUserService userService;
    @Resource
    private MoldBrandService moldBrandService;
    @Resource
    private MoldService moldService;
    @Resource
    private MachineComponentService machineComponentService;

    @Override
    public List<MoldRecordRespVO> buildVOList(List<MoldRecordDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, AdminUserDO> userMap = userService.getUserMap(
                convertSet(list, MoldRecordDO::getUserId));

        Map<Long, MoldBrandDO> brandMap = moldBrandService.getMap(
                convertSet(list, MoldRecordDO::getBrandId));
        Map<Long, MoldDO> moldMap = moldService.getMap(
                convertSet(list, MoldRecordDO::getMoldId));

        Map<Long, MachineComponentDO> machineMap = machineComponentService.getMap(
                convertSet(list, MoldRecordDO::getMachineId));

        return BeanUtils.toBean(list, MoldRecordRespVO.class, item -> {
            MapUtils.findAndThen(userMap, item.getUserId(),
                    user -> item.setUserName(user.getNickname()));

            MapUtils.findAndThen(brandMap, item.getBrandId(),
                    brand -> item.setBrandName(brand.getName()).setBrandType(brand.getMoldType()));

            MapUtils.findAndThen(moldMap, item.getMoldId(),
                    mold -> item.setMoldName(mold.getName()));
            MapUtils.findAndThen(machineMap, item.getMachineId(),
                    ma -> item.setMachineName(ma.getName()));

        });
    }
    // ==================== 子表（模具维保明细） ====================

    @Override
    public List<MoldRecordSubjectDetailDO> getMoldRecordSubjectDetailListByRecordId(Long recordId) {
        return moldRecordSubjectDetailMapper.selectListByRecordId(recordId);
    }

    private void createMoldRecordSubjectDetailList(Long recordId, List<MoldRecordSubjectDetailDO> list) {
        list.forEach(o -> o.setRecordId(recordId));
        moldRecordSubjectDetailMapper.insertBatch(list);
    }

    private void updateMoldRecordSubjectDetailList(Long recordId, List<MoldRecordSubjectDetailDO> list) {
        deleteMoldRecordSubjectDetailByRecordId(recordId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createMoldRecordSubjectDetailList(recordId, list);
    }

    private void deleteMoldRecordSubjectDetailByRecordId(Long recordId) {
        moldRecordSubjectDetailMapper.deleteByRecordId(recordId);
    }

}