package cn.iocoder.yudao.module.smartfactory.service.factorydata;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factorydata.vo.FactoryDataInfoRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factorydata.vo.sizeData.FactoryDataSizeCreateReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factorydata.vo.sizeData.FactoryDataSizeSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.packagedata.vo.PackageDataCreateReqVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorydata.FactoryDataDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorydata.FactoryDataSizeDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.factorydata.FactoryDataSizeMapper;
import cn.iocoder.yudao.module.smartfactory.service.packagedata.PackageDataService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.PACKAGE_DATA_EXISTS;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.SIZEDATA_NOT_EXISTS;

/**
 * 工厂出库入库规格数据 Service 实现类
 *
 * @author 符溶馨
 */
@Service
@Validated
public class FactoryDataSizeServiceImpl implements FactoryDataSizeService{

    @Resource
    private FactoryDataSizeMapper factoryDataSizeMapper;

    @Resource
    private PackageDataService packageDataService;

    @Resource
    @Lazy // 循环依赖，避免报错
    private FactoryDataService factoryDataService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createData(FactoryDataSizeCreateReqVO createReqVO) {

        //校验 当前日期得数据是否已经录入
        Collection<Integer> types = Arrays.asList(1,2,3);
        Long count = factoryDataSizeMapper.selectCountByType(createReqVO.getFactoryId(), createReqVO.getDate(), types);
        if (count > 0L) {
            throw exception(PACKAGE_DATA_EXISTS);
        }

        //校验 当前日期的出库数据是否已经统计过
        FactoryDataDO factoryDataDO = factoryDataService.getListByType(createReqVO.getFactoryId(), createReqVO.getDate(), 1);
        if (factoryDataDO != null) {
            throw exception(PACKAGE_DATA_EXISTS);
        }

        //插入
        List<FactoryDataSizeDO> factoryDataSizeDOs = new ArrayList<>();
        for (FactoryDataSizeSaveReqVO reqVO : createReqVO.getItems()) {

            if (reqVO.getInDamageNum() != null) {

                FactoryDataSizeDO dataSizeDO = BeanUtils.toBean(reqVO, FactoryDataSizeDO.class);

                //设置工厂和日期
                dataSizeDO.setFactoryId(createReqVO.getFactoryId());
                dataSizeDO.setDate(createReqVO.getDate());
                //设置入库破损数
                dataSizeDO.setType(1);
                dataSizeDO.setNum(reqVO.getInDamageNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }

            if (reqVO.getOutNum() != null) {

                FactoryDataSizeDO dataSizeDO = BeanUtils.toBean(reqVO, FactoryDataSizeDO.class);

                //设置工厂和日期
                dataSizeDO.setFactoryId(createReqVO.getFactoryId());
                dataSizeDO.setDate(createReqVO.getDate());
                //设置出库数
                dataSizeDO.setType(2);
                dataSizeDO.setNum(reqVO.getOutNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }

            if (reqVO.getOutDamageNum() != null) {

                FactoryDataSizeDO dataSizeDO = BeanUtils.toBean(reqVO, FactoryDataSizeDO.class);

                //设置工厂和日期
                dataSizeDO.setFactoryId(createReqVO.getFactoryId());
                dataSizeDO.setDate(createReqVO.getDate());
                //设置出库破损数
                dataSizeDO.setType(3);
                dataSizeDO.setNum(reqVO.getOutDamageNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }
        }

        factoryDataSizeMapper.insertBatch(factoryDataSizeDOs);

        // 判断打包线数据不为空时， 同步插入打包线数据
        if (!createReqVO.getPackageData().isEmpty()) {

            PackageDataCreateReqVO packCreateReqVO = new PackageDataCreateReqVO();
            packCreateReqVO.setFactoryId(createReqVO.getPackageData().get(0).getFactoryId());
            packCreateReqVO.setPackageData(createReqVO.getPackageData());
            packCreateReqVO.setPackageDate(createReqVO.getDate());

            //插入打包线数据
            packageDataService.createPackageData(packCreateReqVO);
        }

        return (long) factoryDataSizeDOs.size();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateData(FactoryDataSizeCreateReqVO updateReqVO) {

        // 更新
        List<FactoryDataSizeDO> factoryDataSizeDOs = new ArrayList<>();
        for (FactoryDataSizeSaveReqVO reqVO : updateReqVO.getItems()) {

            if (reqVO.getInDamageNum() != null) {

                FactoryDataSizeDO dataSizeDO = new FactoryDataSizeDO();

                //设置入库破损数
                dataSizeDO.setId(reqVO.getInDamageNumId());
                dataSizeDO.setNum(reqVO.getInDamageNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }

            if (reqVO.getOutNum() != null) {

                FactoryDataSizeDO dataSizeDO = new FactoryDataSizeDO();

                //设置出库数
                dataSizeDO.setId(reqVO.getOutNumId());
                dataSizeDO.setNum(reqVO.getOutNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }

            if (reqVO.getOutDamageNum() != null) {

                FactoryDataSizeDO dataSizeDO = new FactoryDataSizeDO();

                //设置出库破损数
                dataSizeDO.setId(reqVO.getOutDamageNumId());
                dataSizeDO.setNum(reqVO.getOutDamageNum());

                factoryDataSizeDOs.add(dataSizeDO);
            }
        }

        factoryDataSizeMapper.updateBatch(factoryDataSizeDOs);

        // 判断 是否有打包线数据
        if (!updateReqVO.getPackageData().isEmpty()) {

            PackageDataCreateReqVO packCreateReqVO = new PackageDataCreateReqVO();
            packCreateReqVO.setFactoryId(updateReqVO.getFactoryId());
            packCreateReqVO.setPackageDate(updateReqVO.getDate());
            packCreateReqVO.setPackageData(updateReqVO.getPackageData());

            //插入打包线数据
            packageDataService.updatePackageData(packCreateReqVO);
        }
    }

    @Override
    public void deleteData(Long factoryId, String date) {

        LocalDateTime[] dateTimes = {LocalDateTime.now().with(LocalTime.MIN), LocalDateTime.now().with(LocalTime.MAX)};

        //校验是否 为当天数据
        Long count = factoryDataSizeMapper.selectCountByFactoryId(factoryId, date, dateTimes);
        if (count == 0L) {
            throw exception(SIZEDATA_NOT_EXISTS);
        }

        // 删除
        factoryDataSizeMapper.deleteByFactoryId(factoryId, date);
    }

    @Override
    public List<FactoryDataInfoRespVO> getDetailList(Long factoryId, LocalDate[] date) {

        return factoryDataSizeMapper.selectDetailList(factoryId, date);
    }

    @Override
    public List<FactoryDataInfoRespVO> getSUMByDateTimes(LocalDateTime[] dateTimes) {

        return factoryDataSizeMapper.selectSUMByDateTimes(dateTimes);
    }
}
