package com.clx.performance.service.impl.linewarn;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.dao.linewarn.LineWarnInfoDao;
import com.clx.performance.dao.linewarn.LineWarnLogDao;
import com.clx.performance.dao.linewarn.LineWarnRangeDao;
import com.clx.performance.dto.linewarn.LineWarnOrderChildStatisticsDTO;
import com.clx.performance.enums.ResultEnum;
import com.clx.performance.enums.linewarn.LineWarnInfoEnum;
import com.clx.performance.enums.linewarn.LineWarnLogEnum;
import com.clx.performance.enums.linewarn.LineWarnRangEnum;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.linewarn.LineWarnInfo;
import com.clx.performance.model.linewarn.LineWarnLog;
import com.clx.performance.model.linewarn.LineWarnRange;
import com.clx.performance.param.pc.linewarn.LineWarnInfoResolveUpdateParam;
import com.clx.performance.param.pc.linewarn.LineWarnInfoSuspendUpdateParam;
import com.clx.performance.param.pc.linewarn.PageLineWarnInfoParam;
import com.clx.performance.service.linewarn.LineWarnInfoService;
import com.clx.performance.struct.linewarn.LineWarnInfoStruct;
import com.clx.performance.utils.LocalDateTimeUtils;
import com.clx.performance.vo.pc.linewarn.LineWarnInfoVO;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class LineWarnInfoServiceImpl implements LineWarnInfoService {

    @Autowired
    private LineWarnInfoDao lineWarnInfoDao;
    @Autowired
    private LineWarnLogDao lineWarnLogDao;
    @Autowired
    private LineWarnRangeDao lineWarnRangeDao;

    @Autowired
    private LineWarnInfoStruct lineWarnInfoStruct;

    @Autowired
    private OrderChildDao orderChildDao;
    @Autowired
    private OrderGoodsDao orderGoodsDao;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSuspend(LineWarnInfoSuspendUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        LocalDateTime endTime = LocalDateTimeUtils.parseTime(param.getWarnEndTime());

        LineWarnInfo lineWarnInfo = lineWarnInfoDao.findById(param.getId()).orElseThrow(ResultEnum.DATA_NOT_FIND);

        lineWarnInfo.setSuspendTime(endTime);
        lineWarnInfoDao.updateSuspendTime(lineWarnInfo);

        LineWarnLog lineWarnLog = new LineWarnLog();
        lineWarnLog.setInfoId(lineWarnInfo.getId());
        lineWarnLog.setType(LineWarnLogEnum.Type.SUSPEND.getCode());
        lineWarnLog.setContent(LineWarnLogEnum.Type.SUSPEND.getMsg());
        lineWarnLog.setOrderGoodsNo(lineWarnInfo.getOrderGoodsNo());
        lineWarnLog.setWarnName(lineWarnInfo.getWarnName());
        lineWarnLog.setWarnEndTime(endTime);
        lineWarnLog.setWarnTime(lineWarnInfo.getWarnTime());
        lineWarnLog.setCreateBy(loginUserInfo.getUserName());
        lineWarnLogDao.saveEntity(lineWarnLog);

        LineWarnRange lineWarnRange = new LineWarnRange();
        lineWarnRange.setWarnConfigId(lineWarnInfo.getWarnConfigId());
        lineWarnRange.setWarnName(lineWarnInfo.getWarnName());
        lineWarnRange.setOrderGoodsNo(lineWarnInfo.getOrderGoodsNo());
        lineWarnRange.setWarnEndTime(endTime);
        lineWarnRange.setStatus(LineWarnRangEnum.Status.ENABLE.getCode());
        lineWarnRange.setCreateBy(loginUserInfo.getUserName());

        // 禁用旧数据
        lineWarnRangeDao.updateDisable(lineWarnRange);
        // 新增新数据
        lineWarnRangeDao.saveEntity(lineWarnRange);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateResolve(LineWarnInfoResolveUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        LineWarnInfo lineWarnInfo = lineWarnInfoDao.findById(param.getId()).orElseThrow(ResultEnum.DATA_NOT_FIND);
        lineWarnInfo.setStatus(LineWarnInfoEnum.Status.RESOLVE.getCode());
        lineWarnInfoDao.updateStatus(lineWarnInfo);

        LineWarnLog lineWarnLog = new LineWarnLog();
        lineWarnLog.setInfoId(lineWarnInfo.getId());
        lineWarnLog.setType(LineWarnLogEnum.Type.RESOLVE.getCode());
        lineWarnLog.setContent(LineWarnLogEnum.Type.RESOLVE.getMsg());
        lineWarnLog.setOrderGoodsNo(lineWarnInfo.getOrderGoodsNo());
        lineWarnLog.setWarnName(lineWarnInfo.getWarnName());
        lineWarnLog.setWarnTime(lineWarnInfo.getWarnTime());
        lineWarnLog.setCreateBy(loginUserInfo.getUserName());

        lineWarnLogDao.saveEntity(lineWarnLog);
    }

    @Override
    public LineWarnInfoVO getInfo(Integer id) {
        return lineWarnInfoStruct.convert(lineWarnInfoDao.findById(id).orNull());

    }

    @Override
    public IPage<LineWarnInfoVO> pageInfo(PageLineWarnInfoParam param) {
        Page<LineWarnInfoVO> page = lineWarnInfoStruct.convertPage(lineWarnInfoDao.pageByParam(param));

        // 更新车数统计数据
        List<String> orderGoodsNoList = page.getRecords().stream().map(item -> item.getOrderGoodsNo()).collect(Collectors.toList());
        if (!orderGoodsNoList.isEmpty()) {
            List<OrderGoods> pengList = orderGoodsDao.selectListByOrderGoodsList(orderGoodsNoList);

            List<LineWarnOrderChildStatisticsDTO> takeList = orderChildDao.sumTakeNumByOrderGoodsNoList(orderGoodsNoList);
            List<LineWarnOrderChildStatisticsDTO> sendList = orderChildDao.sumArriveSendNumByOrderGoodsNoList(orderGoodsNoList);
            List<LineWarnOrderChildStatisticsDTO> loadList = orderChildDao.sumLoadNumByOrderGoodsNoList(orderGoodsNoList);
            List<LineWarnOrderChildStatisticsDTO> receiveList = orderChildDao.sumArriveRecieveNumByOrderGoodsNoList(orderGoodsNoList);
            List<LineWarnOrderChildStatisticsDTO> unloadList = orderChildDao.sumUnloadNumByOrderGoodsNoList(orderGoodsNoList);

            Map<String, OrderGoods> pengMap = pengList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));
            Map<String, LineWarnOrderChildStatisticsDTO> takeMap = takeList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));
            Map<String, LineWarnOrderChildStatisticsDTO> sendMap = sendList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));
            Map<String, LineWarnOrderChildStatisticsDTO> loadMap = loadList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));
            Map<String, LineWarnOrderChildStatisticsDTO> receiveMap = receiveList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));
            Map<String, LineWarnOrderChildStatisticsDTO> unloadMap = unloadList.stream().collect(Collectors.toMap(item -> item.getOrderGoodsNo(), item -> item));

            for (LineWarnInfoVO item : page.getRecords()) {
                item.setPengNum(pengMap.get(item.getOrderGoodsNo()) == null? 0:pengMap.get(item.getOrderGoodsNo()).getNeedTruckNum());
                item.setTakeNum(takeMap.get(item.getOrderGoodsNo()) == null? 0:takeMap.get(item.getOrderGoodsNo()).getNum());
                item.setArriveSendNum(sendMap.get(item.getOrderGoodsNo()) == null? 0:sendMap.get(item.getOrderGoodsNo()).getNum());
                item.setLoadNum(loadMap.get(item.getOrderGoodsNo()) == null? 0:loadMap.get(item.getOrderGoodsNo()).getNum());
                item.setArriveReceiveNum(receiveMap.get(item.getOrderGoodsNo()) == null? 0:receiveMap.get(item.getOrderGoodsNo()).getNum());
                item.setUnloadNum(unloadMap.get(item.getOrderGoodsNo()) == null? 0:unloadMap.get(item.getOrderGoodsNo()).getNum());
            }

        }
        return page;

    }
}
