package cn.iocoder.yudao.module.smartfactory.framework.job.factoryData;

import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factorydata.vo.FactoryDataInfoRespVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorydata.FactoryDataDO;
import cn.iocoder.yudao.module.smartfactory.service.factorydata.FactoryDataService;
import cn.iocoder.yudao.module.smartfactory.service.factorydata.FactoryDataSizeService;
import cn.iocoder.yudao.module.smartfactory.service.packagedata.PackageDataService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * 工厂 出入库数据统计 定时任务
 */
@Component
@Slf4j
public class FactoryDataJob {

    @Resource
    private FactoryDataSizeService dataSizeService;

    @Resource
    private PackageDataService packageDataService;

    @Resource
    private FactoryDataService factoryDataService;

    @XxlJob("factoryDataJob")
    @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意
    public ReturnT<String> execute() throws Exception {

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

        //查询 当前统计时间前一天的的打包线数据
        List<FactoryDataDO> factoryDataDOS = packageDataService.getDataListByDateTime(dateTimes);

        //查询 当前统计时间前一天的的出入库规格数据
        List<FactoryDataInfoRespVO> infoRespVOS = dataSizeService.getSUMByDateTimes(dateTimes);

        List<FactoryDataDO> outFactoryDataDOs = new ArrayList<>();

        //处理入库数据
        factoryDataDOS.forEach(data -> {

            //设置 出入库类型为 入库
            data.setDataType(2);
            data.setCreator(Objects.requireNonNull(getLoginUserId()).toString());

            //取出 同一个工厂和日期的数据
            List<FactoryDataInfoRespVO> infos = infoRespVOS.stream()
                    .filter(info -> info.getFactoryId().equals(data.getFactoryId()) && info.getDate().equals(data.getDate()))
                    .collect(Collectors.toList());

            if (!infos.isEmpty()) {

                if (infos.get(0).getInDamageNum() != null) {

                    // 设置 入库破损数
                    data.setDamageNum(data.getDamageNum() + infos.get(0).getInDamageNum());
                }

                // 如果存在出库数时
                if (infos.get(0).getOutNum() != null) {

                    FactoryDataDO dataDO = new FactoryDataDO();

                    dataDO.setFactoryId(data.getFactoryId());
                    dataDO.setDate(data.getDate());
                    dataDO.setDataType(1);
                    dataDO.setTotalNum(infos.get(0).getOutNum());
                    dataDO.setDamageNum(infos.get(0).getOutDamageNum());
                    dataDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());

                    outFactoryDataDOs.add(dataDO);
                }
            }

            // 移除已处理过的 入库数据
            infoRespVOS.removeAll(infos);
        });

        // 插入 出库数据
        for (FactoryDataInfoRespVO infoRespVO : infoRespVOS) {

            FactoryDataDO dataDO = new FactoryDataDO();

            dataDO.setFactoryId(infoRespVO.getFactoryId());
            dataDO.setDate(infoRespVO.getDate());
            dataDO.setDataType(1);
            dataDO.setTotalNum(infoRespVO.getOutNum());
            dataDO.setDamageNum(infoRespVO.getOutDamageNum());
            dataDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());

            outFactoryDataDOs.add(dataDO);
        }

        // 插入
        factoryDataDOS.addAll(outFactoryDataDOs);
        factoryDataService.createData(factoryDataDOS);

        // 返回执行成功
        return ReturnT.SUCCESS;
    }
}
