package com.cf.imes.module.manage.service.remainplaten;

import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.module.manage.controller.admin.plate.vo.remain.RemainPlatePageReqVO;
import com.cf.imes.module.manage.controller.admin.plate.vo.remain.RemainPlateSaveReqVO;
import com.cf.imes.module.manage.dal.dataobject.remainplaten.RemainPlateDO;
import com.cf.imes.module.manage.dal.mysql.remainplaten.RemainPlateMapper;
import com.cf.imes.module.manage.enums.RemainPlateStatusEnum;
import com.cf.imes.module.manage.enums.RemainPlateUseTypeEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.cf.imes.framework.common.pojo.PageResult;


import com.cf.imes.framework.common.util.object.BeanUtils;

import javax.annotation.Resource;

import java.util.*;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;

/**
 * 生产单余料板表 order_remain_plate_{N} Service 实现类
 *
 * @author 晨丰科技
 */
@Service
@Validated
public class RemainPlateServiceImpl implements RemainPlateService {

    @Resource
    private RemainPlateMapper remainPlateMapper;

    @Override
    public Long createRemainPlate(RemainPlateSaveReqVO createReqVO) {
        // 插入
        RemainPlateDO remainPlate = BeanUtils.toBean(createReqVO, RemainPlateDO.class);
        remainPlateMapper.insert(remainPlate);
        // 返回
        return remainPlate.getId();
    }

    @Override
    public Boolean createRemainPlateMultiple(Set<RemainPlateSaveReqVO> createReqVOS) {
        Collection<RemainPlateDO> remainPlates = new ArrayList<>();
        createReqVOS.forEach(createReqVO -> {
            RemainPlateDO remainPlate = BeanUtils.toBean(createReqVO, RemainPlateDO.class);
            remainPlates.add(remainPlate);
        });
        return remainPlateMapper.insertBatch(remainPlates);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRemainPlateStatus(Set<Long> ids, Integer status, Integer useType,Long planId) {
        //判断是否符合核销标准
        validateRemainPlateStatus(ids,RemainPlateStatusEnum.IN_USE.getStatus());
        //以id为条件批量修改余料库中的状态
        remainPlateMapper.updateRemainPlateStatus(ids, status, useType, OrganContextHolder.getOrganId(),planId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revertRemainPlateStatus(Set<Long> ids, Integer status) {
        // 判断余料的状态是否存在使用中
        validateRemainPlateStatus(ids,RemainPlateStatusEnum.UNUSED.getStatus());
        // 判断使用类型是否为核销
        for (Long id : ids) {
            if (validateRemainPlateUseType(id).equals( RemainPlateUseTypeEnum.TYPE_ONE.getStatus())) {
                throw exception(REMAIN_PLATE_USR_TYPE);
            }
        }
        remainPlateMapper.updateRemainPlateStatus(ids, status, null, OrganContextHolder.getOrganId(),0L);
    }

    @Override
    public void updateRemainPlate(RemainPlateSaveReqVO updateReqVO) {
        // 校验存在
        validateRemainPlateExists(updateReqVO.getId());
        // 是否使用
        if (validateRemainPlateStatus(updateReqVO.getId()) == RemainPlateStatusEnum.IN_USE.getStatus()){
            throw exception(REMAIN_PLATE_STATUS_USED);
        }
        // 判断是否为开料添加
        RemainPlateDO updateObj = new RemainPlateDO();
        if (validateRemainPlateIsCutting(updateReqVO.getId())){
            updateObj.setRemark(updateReqVO.getRemark());
        }else {
            // 更新
            updateObj = BeanUtils.toBean(updateReqVO, RemainPlateDO.class);
        }
        remainPlateMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRemainPlate(Set<Long> ids) {
        // 判断余料的状态是否存在使用中
        validateRemainPlateStatus(ids,RemainPlateStatusEnum.IN_USE.getStatus());
        // 删除
        remainPlateMapper.deleteBatchIds(ids);
    }

    // 判断余料板是否正在使用
    private void validateRemainPlateStatus(Set<Long> ids, Integer status) {
        for (Long id : ids) {
            if (validateRemainPlateStatus(id) == status) {
                if (status == RemainPlateStatusEnum.IN_USE.getStatus())
                    throw exception(REMAIN_PLATE_STATUS_USED);
                if (status == RemainPlateStatusEnum.UNUSED.getStatus())
                    throw exception(REMAIN_PLATE_STATUS_NO_USED);
            }
        }
    }

    private void validateRemainPlateExists(Long id) {
        if (remainPlateMapper.selectById(id) == null) {
            throw exception(REMAIN_PLATE_NOT_EXISTS);
        }
    }

    private boolean validateRemainPlateIsCutting(Long id) {
       return remainPlateMapper.selectById(id).getIsCutting();
    }

    private Integer validateRemainPlateStatus(Long id) {
        return remainPlateMapper.selectById(id).getStatus();
    }

    private Integer validateRemainPlateUseType(Long id) {
        return remainPlateMapper.selectById(id).getUseType();
    }

    @Override
    public RemainPlateDO getRemainPlate(Long id) {
        return remainPlateMapper.selectById(id);
    }

    @Override
    public PageResult<RemainPlateDO> getRemainPlatePage(RemainPlatePageReqVO pageReqVO) {
        return remainPlateMapper.selectPage(pageReqVO);
    }

}