package com.prolog.rdc.tms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.RestrictionBuilder;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillHeaderMapper;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.service.LoadingBillService;
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.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hongbo.pan
 * @date 2022/9/29
 */
@Slf4j
@Service
public class LoadingBillServiceImpl implements LoadingBillService {

    @Autowired
    private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

    @Autowired
    private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

    @Autowired
    private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

    /**
     * 更新派车单站点数
     * @param loadingBillId
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStationByLoadingBillId(String loadingBillId) {
        if (StrUtil.isNotBlank(loadingBillId)) {
            updateStationByLoadingBillIdList(Lists.newArrayList(loadingBillId));
        }
    }

    /**
     * 批量更新派车单站点数
     * @param loadingBillIdList
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStationByLoadingBillIdList(List<String> loadingBillIdList) {
        log.info("批量更新派车单站点数=" + JSON.toJSONString(loadingBillIdList));
        if (CollectionUtil.isNotEmpty(loadingBillIdList)) {
            Criteria criteria = new Criteria(TmsLoadingBillDetailModel.class);
            Restriction rt1 = new RestrictionBuilder()
                    .in("loadingBillId", loadingBillIdList.toArray())
                    .build();
            criteria.setRestriction(rt1);
            //根据派车单id集合查询明细
            List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
            if (CollectionUtil.isNotEmpty(tmsLoadingBillDetailModelList)) {
                //明细按派车单分组
                Map<String, List<TmsLoadingBillDetailModel>> loadingBillMap = tmsLoadingBillDetailModelList.stream().
                        collect(Collectors.groupingBy(TmsLoadingBillDetailModel::getLoadingBillId));
                List<String> shipBillIdList = loadingBillMap.values().stream().flatMap(list ->
                        list.stream().filter(model -> StrUtil.isNotBlank(model.getShipbillId())).
                                map(TmsLoadingBillDetailModel::getShipbillId)).collect(Collectors.toList());
                //查询运单
                List<TmsShipbillHeaderModel> tmsShipBillHeaderModelList = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class,
                        shipBillIdList.toArray(), null);
                if (CollectionUtil.isNotEmpty(tmsShipBillHeaderModelList)) {
                    //按派车单统计站点数并更新
                    loadingBillMap.forEach((key, value) -> {
                        log.info("更新派车单站点数key=" + key + ",value=" + JSON.toJSONString(value));
                        if (CollectionUtil.isNotEmpty(value)) {
                            List<String> idList = value.stream().filter(model -> StrUtil.isNotBlank(model.getShipbillId())).
                                    map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList());
                            List<TmsShipbillHeaderModel> filterShipBillHeaderModelList = tmsShipBillHeaderModelList.stream().
                                    filter(tmsShipBillHeaderModel -> idList.contains(tmsShipBillHeaderModel.getShipbillId())).
                                    collect(Collectors.toList());
                            log.info("派车单=" + key + ",对应运单id=" + JSON.toJSONString(idList));
                            log.info("派车单=" + key + ",对应运单=" + JSON.toJSONString(filterShipBillHeaderModelList));
                            Map<String, Object> updateMap = Maps.newHashMap();
                            updateMap.put("pickupStations", 0L);
                            updateMap.put("deliveryStations", 0L);
                            updateMap.put("totalStations", 0L);
                            updateMap.put("cargoOwnerNumber", 0L);
                            updateMap.put("coldShipbillNumber", 0L);
                            updateMap.put("urgentShipbillNumber", 0L);
                            updateMap.put("shipbillNumber", 0L);
                            updateMap.put("customerNumber", 0L);
                            updateMap.put("updatetime", new Date());
                            if (CollectionUtil.isNotEmpty(filterShipBillHeaderModelList)) {
                                long pickupStations = filterShipBillHeaderModelList.stream().filter(model ->
                                        StrUtil.isNotBlank(model.getShipperAddress())).
                                        map(TmsShipbillHeaderModel::getShipperAddress).map(StrUtil::trim).distinct().count();
                                long deliveryStations = filterShipBillHeaderModelList.stream().filter(model ->
                                                StrUtil.isNotBlank(model.getConsigneeAddress())).
                                        map(TmsShipbillHeaderModel::getConsigneeAddress).map(StrUtil::trim).distinct().count();
                                long totalStations = pickupStations + deliveryStations;
                                updateMap.put("pickupStations", pickupStations);
                                updateMap.put("deliveryStations", deliveryStations);
                                updateMap.put("totalStations", totalStations);
                                updateMap.put("cargoOwnerNumber", filterShipBillHeaderModelList.stream().map(TmsShipbillHeaderModel::getCargoOwnerId).filter(ObjectUtil::isNotNull).distinct().count());
                                updateMap.put("coldShipbillNumber", filterShipBillHeaderModelList.stream().map(TmsShipbillHeaderModel::getTemperatureRequirement).
                                        filter(temperatureRequirement -> ObjectUtil.isNotNull(temperatureRequirement) && !DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.equals(temperatureRequirement)).count());
                                updateMap.put("urgentShipbillNumber", filterShipBillHeaderModelList.stream().map(TmsShipbillHeaderModel::getOrderType).
                                        filter(orderType -> ObjectUtil.isNotNull(orderType) && !DataDictionaryConstant.ORDER_TYPE_P.equals(orderType)).count());
                                updateMap.put("shipbillNumber", filterShipBillHeaderModelList.size());
                                updateMap.put("customerNumber", filterShipBillHeaderModelList.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsShipbillHeaderModel::getConsigneeName).distinct().count());
                            }
                            log.info("更新派车单=" + key + ",站点数=" + JSON.toJSONString(updateMap));
                            tmsLoadingBillHeaderMapper.updateMapById(key, updateMap, TmsLoadingBillHeaderModel.class);
                        }
                    });
                }
            }
        }
    }

    @Override
    public TmsLoadingBillHeaderModel setLoadingBillDelivery(TmsLoadingBillHeaderModel loadingBillHeaderModel) {
        Criteria criteria = new Criteria(TmsLoadingBillDetailModel.class);
        Restriction rt1 = new RestrictionBuilder()
                .eq(TmsLoadingBillDetailModel::getLoadingBillId, loadingBillHeaderModel.getLoadingBillId())
                .build();
        criteria.setRestriction(rt1);
        //根据派车单id集合查询明细
        List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
        if (CollectionUtil.isNotEmpty(tmsLoadingBillDetailModelList)) {
            loadingBillHeaderModel.setTotalDeliveryPcs(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getTotalDeliveryPcs).reduce(BigDecimal.ZERO, NumberUtil::add));
            loadingBillHeaderModel.setTotalDeliveryWeight(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getTotalDeliveryWeight).reduce(BigDecimal.ZERO, NumberUtil::add));
            loadingBillHeaderModel.setTotalDeliveryVolume(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getTotalDeliveryVolume).reduce(BigDecimal.ZERO, NumberUtil::add));
        }
        return loadingBillHeaderModel;
    }
}
