package com.sckw.transport.service;

import com.alibaba.fastjson2.JSONObject;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.order.api.model.GoodsLoadingParam;
import com.sckw.order.api.model.OrderDetailRes;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.transport.dao.*;
import com.sckw.transport.model.KwtLogisticsOrder;
import com.sckw.transport.model.KwtLogisticsOrderGoods;
import com.sckw.transport.model.KwtLogisticsOrderGoodsUnit;
import com.sckw.transport.model.dto.*;
import com.sckw.transport.model.param.GoodsUnitParam;
import com.sckw.transport.model.param.LogisticsConsignmentParam;
import com.sckw.transport.model.vo.GoodsUnitVo;
import com.sckw.transport.model.vo.WaybillCountVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author zk
 * @desc 物流订单关联商品信息
 * @date 2023/12/6 0006
 */
@Slf4j
@Service
@SuppressWarnings("all")
public class KwtLogisticsOrderGoodsService {
    @Autowired
    KwtWaybillOrderMapper waybillOrderMapper;
    @Autowired
    KwtWaybillOrderV1Mapper waybillOrderV1Mapper;
    @Autowired
    KwtLogisticsOrderMapper logisticsOrderMapper;
    @Autowired
    public KwtLogisticsOrderGoodsMapper goodsMapper;
    @Autowired
    public KwtLogisticsOrderGoodsUnitMapper goodsUnitMapper;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    /**
     * 物流订单-商品信息
     *
     * @param bo       页面请求数据
     * @param lOrderNo 物流订单编号
     * @param orderId  物流订单表编号
     */
    public void insertLogisticsGoods(LogisticsConsignmentParam bo, String lOrderNo, Long orderId) {
        KwtLogisticsOrderGoods kwtLogisticsOrderGoods = new KwtLogisticsOrderGoods();
        kwtLogisticsOrderGoods.setId(new IdWorker(NumberConstant.ONE).nextId());
        kwtLogisticsOrderGoods.setGoodsId(Long.parseLong(bo.getGoodsId()));
        kwtLogisticsOrderGoods.setGoodsName(bo.getGoodsName());
        kwtLogisticsOrderGoods.setSkuId(StringUtils.isBlank(bo.getSkuId()) ? null : Long.parseLong(bo.getSkuId()));
        kwtLogisticsOrderGoods.setLOrderId(orderId);
        kwtLogisticsOrderGoods.setLOrderNo(lOrderNo);
        kwtLogisticsOrderGoods.setUpdateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setUpdateTime(new Date());
        kwtLogisticsOrderGoods.setCreateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setCreateTime(new Date());
        goodsMapper.insert(kwtLogisticsOrderGoods);

        //辅助单位
        List<GoodsUnitParam> assistUnit = bo.getAssistUnit();
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            assistUnit.forEach(e -> {
                KwtLogisticsOrderGoodsUnit unit = BeanUtils.copyProperties(e, KwtLogisticsOrderGoodsUnit.class);
                unit.setGoodsId(kwtLogisticsOrderGoods.getGoodsId());
                unit.setLOrderId(kwtLogisticsOrderGoods.getLOrderId());
                unit.setUnit(unit.getFromUnit().equals(bo.getCarryingCapacityUnit()) ? unit.getToUnit() : unit.getFromUnit());
                goodsUnitMapper.insert(unit);
            });
        }
    }

    /**
     * 物流订单-商品信息
     *
     * @param bo       页面请求数据
     * @param lOrderNo 物流订单编号
     * @param orderId  物流订单表编号
     */
    public void insertLogisticsGoods(LogisticsConsignmentDto bo, String lOrderNo, Long orderId) {
        KwtLogisticsOrderGoods kwtLogisticsOrderGoods = new KwtLogisticsOrderGoods();
        kwtLogisticsOrderGoods.setId(new IdWorker(NumberConstant.ONE).nextId());
        kwtLogisticsOrderGoods.setGoodsId(bo.getGoodsId());
        kwtLogisticsOrderGoods.setGoodsName(bo.getGoodsName());
        kwtLogisticsOrderGoods.setSkuId(StringUtils.isBlank(bo.getSkuId()) ? null : Long.parseLong(bo.getSkuId()));
        kwtLogisticsOrderGoods.setLOrderId(orderId);
        kwtLogisticsOrderGoods.setLOrderNo(lOrderNo);
        kwtLogisticsOrderGoods.setUpdateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setUpdateTime(new Date());
        kwtLogisticsOrderGoods.setCreateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setCreateTime(new Date());
        goodsMapper.insert(kwtLogisticsOrderGoods);

        //辅助单位
        List<GoodsUnitParam> assistUnit = bo.getAssistUnit();
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            assistUnit.forEach(e -> {
                KwtLogisticsOrderGoodsUnit unit = BeanUtils.copyProperties(e, KwtLogisticsOrderGoodsUnit.class);
                unit.setGoodsId(kwtLogisticsOrderGoods.getGoodsId());
                unit.setLOrderId(kwtLogisticsOrderGoods.getLOrderId());
                unit.setUnit(unit.getFromUnit().equals(bo.getCarryingCapacityUnit()) ? unit.getToUnit() : unit.getFromUnit());
                goodsUnitMapper.insert(unit);
            });
        }
    }

    /**
     * 分包托运-承运订单-商品信息
     *
     * @param bo
     * @param lOrderNo
     * @param orderId
     */
    public void insertSubcontractLogisticsGoods(KwtLogisticsOrder logisticsOrder, String lOrderNo, Long orderId) {
        KwtLogisticsOrderGoods superiorGodds = goodsMapper.findByGoods(logisticsOrder.getId());
        KwtLogisticsOrderGoods kwtLogisticsOrderGoods = new KwtLogisticsOrderGoods();
        kwtLogisticsOrderGoods.setId(new IdWorker(NumberConstant.ONE).nextId());
        kwtLogisticsOrderGoods.setLOrderId(orderId);
        kwtLogisticsOrderGoods.setLOrderNo(lOrderNo);
        kwtLogisticsOrderGoods.setGoodsId(superiorGodds != null ? superiorGodds.getGoodsId() : null);
        kwtLogisticsOrderGoods.setGoodsName(superiorGodds != null ? superiorGodds.getGoodsName() : null);
        kwtLogisticsOrderGoods.setGoodsType(superiorGodds != null ? superiorGodds.getGoodsType() : null);
        kwtLogisticsOrderGoods.setSkuId(superiorGodds != null ? superiorGodds.getSkuId() : null);
        kwtLogisticsOrderGoods.setRemark(superiorGodds != null ? superiorGodds.getRemark() : null);
        kwtLogisticsOrderGoods.setUpdateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setUpdateTime(new Date());
        kwtLogisticsOrderGoods.setCreateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setCreateTime(new Date());
        goodsMapper.insert(kwtLogisticsOrderGoods);

        //辅助单位
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN) {{
            put("lOrderId", logisticsOrder.getId());
        }});
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            assistUnit.forEach(e -> {
                KwtLogisticsOrderGoodsUnit unit = new KwtLogisticsOrderGoodsUnit();
                unit.setLOrderId(orderId);
                unit.setGoodsId(e.getGoodsId());
                unit.setFromUnit(e.getFromUnit());
                unit.setToUnit(e.getToUnit());
                unit.setConversionValue(e.getConversionValue());
                unit.setUnit(e.getUnit());
                unit.setRemark(e.getRemark());
                goodsUnitMapper.insert(unit);
            });
        }
    }

    /**
     * 承运订单-页面新增订单-商品信息
     *
     * @param orderDTO 页面参数
     * @param lOrderId 订单id
     * @param lOrderNo 订单编号
     */
    public void saveLogisticsOrderGoods(AddOrderDTO orderDTO, Long lOrderId, String lOrderNo) {
        KwtLogisticsOrderGoods goods = new KwtLogisticsOrderGoods();
        goods.setId(new IdWorker(NumberConstant.ONE).nextId());
        goods.setLOrderId(lOrderId);
        goods.setLOrderNo(lOrderNo);
        goods.setGoodsName(orderDTO.getGoodsName());
        goods.setGoodsType(orderDTO.getGoodsType());
        goods.setStatus(NumberConstant.ZERO);
        goods.setCreateBy(LoginUserHolder.getUserId());
        goods.setCreateTime(new Date());
        goods.setUpdateBy(LoginUserHolder.getUserId());
        goods.setUpdateTime(new Date());
        goodsMapper.insert(goods);
    }

    /**
     * 更新物流订单商品辅助单位-装卸货量(当前层级)
     * @param lOrderId 物流订单
     */
    public void editLogisticsOrderGoodsLoading(Long lOrderId) {
        //辅助单位
        Map<String, Object> queryParams = new HashMap<>(NumberConstant.SIXTEEN);
        queryParams.put("lOrderId", lOrderId);
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(queryParams);
        //数据处理
        for (KwtLogisticsOrderGoodsUnit goodsUnit:assistUnit) {
            //车辆运单统计(运输中的物流订单+车辆运单审核通过)
            queryParams.clear();
            //装货统计
            queryParams.put("unit", goodsUnit.getUnit());
            queryParams.put("type", NumberConstant.ONE);
            queryParams.put("lOrderId", lOrderId);
            queryParams.put("passStatus", Global.NUMERICAL_ONE);
            WaybillCountVo loadCount = waybillOrderV1Mapper.findTicketCountByAddress(queryParams);
            //卸货统计
            queryParams.put("type", NumberConstant.TWO);
            WaybillCountVo unloadCount = waybillOrderV1Mapper.findTicketCountByAddress(queryParams);
            goodsUnit.setLoadAmount(loadCount.getAmount());
            goodsUnit.setUnloadAmount(unloadCount.getAmount());
            goodsUnitMapper.updateById(goodsUnit);
        }
    }

    /**
     * 更新物流订单商品辅助单位-装卸货量(当前层级+下级)
     * @param lOrderId 物流订单
     */
    public void editLogisticsOrderGoodsTotalLoading(Long lOrderId) {
        //辅助单位
        Map<String, Object> queryParams = new HashMap<>(NumberConstant.SIXTEEN);
        queryParams.put("lOrderId", lOrderId);
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(queryParams);
        //数据处理
        for (KwtLogisticsOrderGoodsUnit goodsUnit:assistUnit) {
            //下级物流订单-辅助单位
            queryParams.clear();
            queryParams.put("belowlOrderId", lOrderId);
            queryParams.put("unit", goodsUnit.getUnit());
            KwtLogisticsOrderGoodsUnit unitCount = goodsUnitMapper.findGoodsUnitCount(queryParams);
            //更新物流订单商品辅助单位-总装卸货量
            goodsUnit.setTotalLoadAmount(unitCount.getTotalLoadAmount().add(goodsUnit.getLoadAmount()));
            goodsUnit.setTotalUnloadAmount(unitCount.getTotalUnloadAmount().add(goodsUnit.getUnloadAmount()));
            goodsUnitMapper.updateById(goodsUnit);
        }
    }

    /**
     * 完结物流订单更新商品辅助单位
     * @param params 完结参数
     */
    public void editLogisticsOrderGoodsTotalLoading(OrderManualCompletionDto params) {
        //辅助单位
        Map<String, Object> queryParams = new HashMap<>(NumberConstant.SIXTEEN);
        queryParams.put("lOrderId", params.getId());
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(queryParams);
        //数据处理
        List<OrderGoodsLoadingDto> loading = params.getLoading();
        for (KwtLogisticsOrderGoodsUnit goodsUnit:assistUnit) {
            for (OrderGoodsLoadingDto goodsLoading : loading) {
                if (goodsLoading.getUnit().equals(goodsUnit.getUnit())) {
                    //更新物流订单商品辅助单位-总装卸货量
                    goodsUnit.setTotalLoadAmount(goodsLoading.getLoadAmount());
                    goodsUnit.setTotalUnloadAmount(goodsLoading.getUnloadAmount());
                    goodsUnitMapper.updateById(goodsUnit);
                }
            }
        }
    }

    /**
     * 完结物流订单更新商品辅助单位
     * @param params 完结参数
     */
    public void editLogisticsOrderGoodsTotalLoadingV42(LogisticsOrderFinishDto params) {
        //辅助单位
        Map<String, Object> queryParams = new HashMap<>(NumberConstant.SIXTEEN);
        queryParams.put("lOrderId", params.getId());
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(queryParams);
        //数据处理
        List<OrderGoodsLoadingDto> loading = params.getLoading();
        for (KwtLogisticsOrderGoodsUnit goodsUnit:assistUnit) {
            for (OrderGoodsLoadingDto goodsLoading : loading) {
                if (goodsLoading.getUnit().equals(goodsUnit.getUnit())) {
                    //更新物流订单商品辅助单位-总装卸货量
                    goodsUnit.setTotalLoadAmount(goodsLoading.getLoadAmount());
                    goodsUnit.setTotalUnloadAmount(goodsLoading.getUnloadAmount());
                    goodsUnitMapper.updateById(goodsUnit);
                }
            }
        }
    }

    /**
     * 物流托运校验贸易订单可派量
     *
     * @param logisticsOrder 派车参数
     * @param tradeOrder     贸易订单
     * @return true 校验通过
     */
    public boolean chenkAmount(LogisticsConsignmentParam logisticsOrder, OrderDetailRes tradeOrder) {
        List<GoodsUnitParam> assistUnit = logisticsOrder.getAssistUnit();
        BigDecimal amount = tradeOrder.getAmount().subtract(tradeOrder.getEntrustAmount());
        BigDecimal arryingCapacity = logisticsOrder.getCarryingCapacity();
        String unit = tradeOrder.getUnit();
        if (logisticsOrder.getCarryingCapacityUnit().equals(unit)) {
            if (amount.compareTo(arryingCapacity) >= 0) {
                return true;
            }
        } else {
            if (CollectionUtils.isEmpty(assistUnit)) {
                return false;
            }
            //辅助单位
            for (GoodsUnitParam goodsUnit : assistUnit) {
                BigDecimal conversionValue = goodsUnit.getConversionValue();
                if (logisticsOrder.getCarryingCapacityUnit().equals(goodsUnit.getFromUnit())) {
                    BigDecimal value = arryingCapacity.multiply(conversionValue);
                    if (amount.compareTo(value) >= 0) {
                        return true;
                    }
                }
                if (logisticsOrder.getCarryingCapacityUnit().equals(goodsUnit.getToUnit())) {
                    BigDecimal value = arryingCapacity.divide(conversionValue);
                    if (amount.compareTo(value) >= 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 获取物流订单辅助单位信息
     *
     * @param lOrderId 物流订单
     * @return 辅助单位信息
     */
    public List<GoodsUnitVo> assistUnit(Long lOrderId) {
        List<GoodsUnitVo> units = new ArrayList<>();
        //辅助单位
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN) {{
            put("lOrderId", lOrderId);
        }});

        if (CollectionUtils.isNotEmpty(assistUnit)) {
            //单位
            Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.UNIT_TYPE.getType()));
            Map<String, String> unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            if (CollectionUtils.isNotEmpty(dict)) {
                unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            }

            Map<String, String> finalUnitMap = unitMap;
            units = BeanUtils.copyToList(assistUnit, GoodsUnitVo.class);
            units.forEach(e -> {
                e.setFromUnitName(finalUnitMap != null ? finalUnitMap.get(e.getFromUnit()) : null);
                e.setToUnitName(finalUnitMap != null ? finalUnitMap.get(e.getToUnit()) : null);
            });
        }
        return units;
    }

    /**
     * 获取物流订单辅助单位信息
     *
     * @param lOrderId 物流订单
     * @return 辅助单位信息
     */
    public List<KwtLogisticsOrderGoodsUnit> findGoodsUnit(Long lOrderId) {
        //辅助单位
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN) {{
            put("lOrderId", lOrderId);
        }});
        return assistUnit;
    }

    /**
     * 贸易订单参数处理-物流订单完结
     *
     * @param logisticsOrder 物流订单
     * @param loading        装载信息
     * @return 贸易订单
     */
    public List<GoodsLoadingParam> goodsLoadingParams(KwtLogisticsOrder logisticsOrder, List<OrderGoodsLoadingDto> loading) {
        List<GoodsLoadingParam> loadingParams = new ArrayList<>();
        //辅助单位
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN) {{
            put("lOrderId", logisticsOrder.getId());
        }});
        //数据处理
        if (CollectionUtils.isNotEmpty(loading)) {
            loading.forEach(e -> {
                BigDecimal loadAmount = e.getLoadAmount();
                if (e.getUnit().equals(logisticsOrder.getUnit())) {
                    loadingParams.add(new GoodsLoadingParam(e.getUnit(), logisticsOrder.getAmount(), loadAmount));
                } else {
                    if (CollectionUtils.isNotEmpty(assistUnit)) {
                        assistUnit.forEach(ee -> {
                            BigDecimal conversionValue = ee.getConversionValue();
                            if (e.getUnit().equals(ee.getFromUnit())) {
                                BigDecimal value = loadAmount.multiply(conversionValue);
                                loadingParams.add(new GoodsLoadingParam(e.getUnit(), value, loadAmount));
                            }
                            if (e.getUnit().equals(ee.getToUnit())) {
                                BigDecimal value = loadAmount.divide(conversionValue);
                                loadingParams.add(new GoodsLoadingParam(e.getUnit(), value, loadAmount));
                            }
                        });
                    }
                }
            });
        }
        return loadingParams;
    }

    /**
     * 贸易订单参数处理-物流订单撤销/物流委托
     *
     * @param logisticsOrder 物流订单
     * @param operator       运算符正负，贸易订单加减（true 正、false 减）
     * @return 贸易订单
     */
    public List<GoodsLoadingParam> goodsLoadingParams(KwtLogisticsOrder logisticsOrder, boolean operator) {
        List<GoodsLoadingParam> loadingParams = new ArrayList<>();
        //主单位
        BigDecimal amount = logisticsOrder.getAmount();
        loadingParams.add(new GoodsLoadingParam(logisticsOrder.getUnit(), operator ? amount : amount.negate(), logisticsOrder.getTotalLoadAmount()));

        //辅助单位
        List<KwtLogisticsOrderGoodsUnit> assistUnit = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN) {{
            put("lOrderId", logisticsOrder.getId());
        }});
        log.info("assistUnit:{}", JSONObject.toJSONString(assistUnit));
        //数据处理
        if (CollectionUtils.isNotEmpty(assistUnit) && (assistUnit.size() > 0)) {
            for (KwtLogisticsOrderGoodsUnit ee:assistUnit) {
                BigDecimal loadAmount = ee.getTotalLoadAmount() == null ? new BigDecimal("0.00") : ee.getTotalLoadAmount();
                BigDecimal conversionValue = ee.getConversionValue();
                if (ee.getUnit().equals(ee.getFromUnit())) {
                    BigDecimal value = loadAmount.multiply(conversionValue);
                    loadingParams.add(new GoodsLoadingParam(ee.getUnit(), operator ? value : value.negate(), loadAmount));
                }
                if (ee.getUnit().equals(ee.getToUnit())) {
                    BigDecimal value = loadAmount.divide(conversionValue);
                    loadingParams.add(new GoodsLoadingParam(ee.getUnit(), operator ? value : value.negate(), loadAmount));
                }
            }
        }
        return loadingParams;
    }

    public boolean chenkLogisticsAmount(LogisticsConsignmentDto logisticsOrder, OrderDetailRes tradeOrder) {
        List<GoodsUnitParam> assistUnit = logisticsOrder.getAssistUnit();
        BigDecimal amount = tradeOrder.getAmount().subtract(tradeOrder.getEntrustAmount());
        BigDecimal arryingCapacity = logisticsOrder.getCarryingCapacity();
        String unit = tradeOrder.getUnit();
        if (logisticsOrder.getCarryingCapacityUnit().equals(unit)) {
            if (amount.compareTo(arryingCapacity) >= 0) {
                return true;
            }
        } else {
            if (CollectionUtils.isEmpty(assistUnit)) {
                return false;
            }
            //辅助单位
            for (GoodsUnitParam goodsUnit : assistUnit) {
                BigDecimal conversionValue = goodsUnit.getConversionValue();
                if (logisticsOrder.getCarryingCapacityUnit().equals(goodsUnit.getFromUnit())) {
                    BigDecimal value = arryingCapacity.multiply(conversionValue);
                    if (amount.compareTo(value) >= 0) {
                        return true;
                    }
                }
                if (logisticsOrder.getCarryingCapacityUnit().equals(goodsUnit.getToUnit())) {
                    BigDecimal value = arryingCapacity.divide(conversionValue);
                    if (amount.compareTo(value) >= 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
