package com.sckw.transport.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.model.enums.AddressTypeEnum;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.FileUtils;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.NumberUtils;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.transport.dao.*;
import com.sckw.transport.model.*;
import com.sckw.transport.model.dto.WaybillOrderTicketLoadingDto;
import com.sckw.transport.model.vo.WaybillCountVo;
import com.sckw.transport.model.vo.WaybillOrderLoadingVO;
import com.sckw.transport.model.vo.WaybillTicketVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zk
 * @desc 运单榜单
 * @date 2023/7/19 0019
 */
@Slf4j
@Service
//@SuppressWarnings("all")
public class KwtWaybillOrderTicketService {
    @Autowired
    KwtWaybillOrderMapper waybillOrderMapper;
    @Autowired
    KwtLogisticsOrderGoodsUnitMapper goodsUnitMapper;
    @Autowired
    KwtLogisticsOrderAddressMapper logisticsOrderAddressMapper;
    @Autowired
    KwtWaybillOrderV1Mapper waybillOrderV1Mapper;
    @Autowired
    KwtWaybillOrderTicketMapper ticketMapper;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    RemoteSystemService remoteSystemService;

    /**
     * @param loading 装载信息
     * @param unit    运单分配单位
     * @param amount  运单装载量
     * @desc 计算装载量
     * @author zk
     * @date 2023/12/6
     */
    public BigDecimal countAmount(List<WaybillOrderTicketLoadingDto> loading, String unit, BigDecimal amount) {
        if (CollectionUtils.isNotEmpty(loading)) {
            for (WaybillOrderTicketLoadingDto ticket : loading) {
                if (unit.equals(ticket.getUnit())) {
                    return ticket.getAmount();
                }
            }
        }
        return amount;
    }

    /**
     * @param loading     装载信息
     * @param wOrderId    运单ID
     * @param urls        榜单地址
     * @param operateTime 操作时间
     * @param type        装卸货类型
     * @desc 更新办单
     * @author zk
     * @date 2023/12/6
     */
    public void addTicket(List<WaybillOrderTicketLoadingDto> loading, Long wOrderId, String urls, Date operateTime, int type) {
        if (CollectionUtils.isNotEmpty(loading)) {
            loading.forEach(e -> {
                KwtWaybillOrderTicket ticket = new KwtWaybillOrderTicket();
                ticket.setWOrderId(wOrderId);
                ticket.setType(type);
                ticket.setUnit(e.getUnit());
                ticket.setAmount(e.getAmount());
                ticket.setUrls(FileUtils.replaceAllBatch(urls));
                ticket.setOperateTime(operateTime);
                ticketMapper.insert(ticket);
            });
        }
    }

    /**
     * @param loading     装载信息
     * @param wOrderId    运单ID
     * @param wSubtaskId    车辆运单子单ID
     * @param wAddressId    车辆运单地址ID
     * @param urls        榜单地址
     * @param operateTime 操作时间
     * @param type        装卸货类型
     * @desc 更新办单
     * @author zk
     * @date 2023/12/6
     */
    public void addTicketV1(List<WaybillOrderTicketLoadingDto> loading, Long wOrderId, Long wSubtaskId, Long wAddressId, String urls, Date operateTime, int type) {
        if (CollectionUtils.isNotEmpty(loading)) {
            loading.forEach(e -> {
                KwtWaybillOrderTicket ticket = new KwtWaybillOrderTicket();
                ticket.setWOrderId(wOrderId);
                ticket.setWSubtaskId(wSubtaskId);
                ticket.setWAddressId(wAddressId);
                ticket.setType(type);
                ticket.setUnit(e.getUnit());
                ticket.setAmount(e.getAmount());
                ticket.setUrls(FileUtils.replaceAllBatch(urls));
                ticket.setOperateTime(operateTime);
                ticketMapper.insert(ticket);
            });
        }
    }

    /**
     * @param loading     装载信息
     * @param wOrderId    运单ID
     * @param urls        榜单地址
     * @param operateTime 操作时间
     * @param type        装卸货类型
     * @desc 更新办单
     * @author zk
     * @date 2023/12/6
     */
    public void editTicket(List<WaybillOrderTicketLoadingDto> loading, Long wOrderId, String urls, Date operateTime, int type) {
        urls = FileUtils.replaceAllBatch(urls);
        if (CollectionUtils.isNotEmpty(loading)) {
            for (WaybillOrderTicketLoadingDto ticket : loading) {
                KwtWaybillOrderTicket oldTicket = ticketMapper.findWaybillOrderTicketV1(wOrderId, null, type, ticket.getUnit()).get(0);
//                Boolean bool1 = oldTicket.getAmount().doubleValue() == ticket.getAmount().doubleValue();
//                Boolean bool2 = oldTicket.getUrls().equals(urls);

                //对比是否存在更新
//                if (oldTicket != null && bool1 && bool2)  {
//                    continue;
//                }

                //删除
                oldTicket.setDelFlag(Global.YES);
//                waybillOrderTicketMapper.updateById(oldTicket);
                ticketMapper.update(oldTicket,new LambdaUpdateWrapper<KwtWaybillOrderTicket>()
                        .set(KwtWaybillOrderTicket::getDelFlag,1)
                        .eq(KwtWaybillOrderTicket::getId,oldTicket.getId()));
                //新增
                KwtWaybillOrderTicket waybillOrderTicket = new KwtWaybillOrderTicket();
                BeanUtils.copyProperties(oldTicket, waybillOrderTicket);
                waybillOrderTicket.setWOrderId(wOrderId);
                waybillOrderTicket.setType(type);
                waybillOrderTicket.setUnit(ticket.getUnit());
                waybillOrderTicket.setAmount(ticket.getAmount());
                waybillOrderTicket.setUrls(urls);
                waybillOrderTicket.setDelFlag(0);
                waybillOrderTicket.setId(new IdWorker(NumberConstant.ONE).nextId());
                //waybillOrderTicket.setOperateTime(operateTime);
                ticketMapper.insert(waybillOrderTicket);
            }
        }
    }

    /**
     * @param loading     装载信息
     * @param wAddressId    车辆运单地址ID
     * @param urls        榜单地址
     * @param operateTime 操作时间
     * @desc 更新办单
     * @author zk
     * @date 2023/12/6
     */
    public void editTicketV1(List<WaybillOrderTicketLoadingDto> loading, Long wAddressId, String urls, Date operateTime) {
        urls = FileUtils.replaceAllBatch(urls);
        if (CollectionUtils.isNotEmpty(loading)) {
            for (WaybillOrderTicketLoadingDto ticket : loading) {
                KwtWaybillOrderTicket oldTicket = ticketMapper.findWaybillOrderTicketV2(wAddressId, ticket.getUnit());
                log.info("oldTicket:{}", JSON.toJSONString(oldTicket));
                if (oldTicket == null) {
                    continue;
                }
                //删除
                oldTicket.setDelFlag(Global.YES);
                ticketMapper.updateById(oldTicket);

                //新增
                KwtWaybillOrderTicket orderTicket = new KwtWaybillOrderTicket();
                orderTicket.setWOrderId(oldTicket.getWOrderId());
                orderTicket.setWSubtaskId(oldTicket.getWSubtaskId());
                orderTicket.setWAddressId(oldTicket.getWAddressId());
                orderTicket.setType(oldTicket.getType());
                orderTicket.setUnit(oldTicket.getUnit());
                orderTicket.setAmount(ticket.getAmount());
                orderTicket.setUrls(urls);
                orderTicket.setOperateTime(operateTime == null ? oldTicket.getOperateTime() : operateTime);
                ticketMapper.insert(orderTicket);
                log.info("orderTicket:{}", JSON.toJSONString(orderTicket));

            }
        }
    }

    /**
     * 运单详情单证信息
     *
     * @param wOrderId          运单ID
     * @param unit              运单委派单位
     * @param deficitAmount     亏吨
     * @param deficitRealAmount 扣亏量
     * @return 单证信息
     */
    public WaybillTicketVO agreement(Long wOrderId, String unit, String deficitAmount, String deficitRealAmount) {
        WaybillTicketVO waybillTicket = new WaybillTicketVO();
        waybillTicket.setDeficitAmount(NumberUtils.parseBigDecimal(deficitAmount));
        waybillTicket.setDeficitRealAmount(NumberUtils.parseBigDecimal(deficitRealAmount));
        //单位数据字典
        Map<String, SysDictResDto> unitType = remoteSystemService.queryDictMapByType(DictTypeEnum.UNIT_TYPE.getType());
        //装货
        List<KwtWaybillOrderTicket> load = ticketMapper.findWaybillOrderTicket(wOrderId, null , NumberConstant.ONE);
        //卸货
        List<KwtWaybillOrderTicket> unload = ticketMapper.findWaybillOrderTicket(wOrderId, null , NumberConstant.TWO);
        if (CollectionUtils.isNotEmpty(load)) {
            List<WaybillOrderLoadingVO> loadLoading = new ArrayList<>();
            load.forEach(e -> {
                SysDictResDto sysDict = unitType != null ? unitType.get(e.getUnit()) : null;
                waybillTicket.setLoadUrl(FileUtils.splice(e.getUrls()));
                waybillTicket.setLoadTime(e.getOperateTime() == null ? null : e.getOperateTime());
                WaybillOrderLoadingVO loadingVo = new WaybillOrderLoadingVO(e.getUnit(), sysDict != null ? sysDict.getLabel() : null, e.getAmount());
                loadingVo.setMain(unit.equals(e.getUnit()) ? true : false);
                loadLoading.add(loadingVo);
            });
            waybillTicket.setLoadLoading(loadLoading);
        }
        if (CollectionUtils.isNotEmpty(unload)) {
            List<WaybillOrderLoadingVO> unloadLoading = new ArrayList<>();
            unload.forEach(e -> {
                SysDictResDto sysDict = unitType != null ? unitType.get(e.getUnit()) : null;
                waybillTicket.setUnloadUrl(FileUtils.splice(e.getUrls()));
                waybillTicket.setUnloadTime(e.getOperateTime() == null ? null : e.getOperateTime());
                WaybillOrderLoadingVO loadingVo = new WaybillOrderLoadingVO(e.getUnit(), sysDict != null ? sysDict.getLabel() : null, e.getAmount());
                loadingVo.setMain(unit.equals(e.getUnit()) ? true : false);
                unloadLoading.add(loadingVo);
            });
            waybillTicket.setUnloadLoading(unloadLoading);
        }
        return waybillTicket;
    }

    /**
     * 运单详情单证信息(辅助单位)
     * @param subtask 运单-子单
     * @return 单证信息
     */
    public List<WaybillTicketVO> agreement(KwtWaybillOrderSubtask subtask) {
        List<WaybillTicketVO> ticketList = new ArrayList<>();
        //物流订单辅助单位
        List<KwtLogisticsOrderGoodsUnit> goodsUnits = goodsUnitMapper.findList(new HashMap<>(NumberConstant.SIXTEEN){{put("lOrderId", subtask.getLOrderId());}});
        if (CollectionUtils.isEmpty(goodsUnits)) {
            return ticketList;
        }

        //单位
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.UNIT_TYPE.getType()));
        Map<String, String> unitMap = CollectionUtils.isNotEmpty(dict) ? dict.get(DictTypeEnum.UNIT_TYPE.getType()) : new HashMap<>(NumberConstant.SIXTEEN);

        //数据处理
        for (KwtLogisticsOrderGoodsUnit goodsUnit:goodsUnits) {
            WaybillTicketVO waybillTicket = new WaybillTicketVO();
            //装货榜单信息
            List<KwtWaybillOrderTicket> loadTickets = ticketMapper.findWaybillOrderTicketV1(subtask.getWOrderId(), subtask.getId(), AddressTypeEnum.SHIPMENT.getCode(), goodsUnit.getUnit());
            //装货时间
            Optional<KwtWaybillOrderTicket> unloadDate = loadTickets.stream().max(Comparator.comparing(KwtWaybillOrderTicket::getOperateTime));
            //装货地点榜单
            loadTickets.forEach(ticket->{ticket.setUrls(FileUtils.spliceBatch(ticket.getUrls()));});
            String loadUrls = loadTickets.stream().map(KwtWaybillOrderTicket::getUrls).collect(Collectors.joining(", "));
            //装货量
            BigDecimal loadAmount = loadTickets.stream().map(KwtWaybillOrderTicket::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            //卸货榜单信息
            List<KwtWaybillOrderTicket> unloadTickets = ticketMapper.findWaybillOrderTicketV1(subtask.getWOrderId(), subtask.getId(), AddressTypeEnum.TAKE.getCode(), goodsUnit.getUnit());
            //卸货时间
            Optional<KwtWaybillOrderTicket> loadDate = unloadTickets.stream().min(Comparator.comparing(KwtWaybillOrderTicket::getOperateTime));
            //卸货地点榜单
            unloadTickets.forEach(ticket->{ticket.setUrls(FileUtils.spliceBatch(ticket.getUrls()));});
            String unloadUrls = unloadTickets.stream().map(KwtWaybillOrderTicket::getUrls).collect(Collectors.joining(", "));
            //卸货量
            BigDecimal unloadAmount = unloadTickets.stream().map(KwtWaybillOrderTicket::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

            //装货信息
            WaybillOrderLoadingVO load = new WaybillOrderLoadingVO();
            load.setUnit(goodsUnit.getUnit());
            load.setUnitName(unitMap.get(goodsUnit.getUnit()));
            load.setAmount(loadAmount);
            load.setMain(subtask.getUnit().equals(goodsUnit.getUnit()));
            //卸货信息
            WaybillOrderLoadingVO unload = new WaybillOrderLoadingVO();
            unload.setUnit(goodsUnit.getUnit());
            unload.setUnitName(unitMap.get(goodsUnit.getUnit()));
            unload.setAmount(unloadAmount);
            load.setMain(subtask.getUnit().equals(goodsUnit.getUnit()));

            waybillTicket.setUnitLabe(unitMap.get(goodsUnit.getUnit()));
            waybillTicket.setLoadUrl(loadUrls);
            waybillTicket.setLoadTime(unloadDate.get().getOperateTime());
            waybillTicket.setLoadWeight(loadAmount);
            waybillTicket.setUnloadUrl(unloadUrls);
            waybillTicket.setUnloadTime(loadDate.get().getOperateTime());
            waybillTicket.setUnloadWeight(unloadAmount);
            waybillTicket.setDeficitAmount(loadAmount.subtract(unloadAmount));
            ticketList.add(waybillTicket);
        }
        return ticketList;
    }

    /**
     * 单证信息
     *
     * @param waybillOrder 运单
     * @param type         单证类型
     * @return 运载信息
     */
    public List<WaybillOrderLoadingVO> agreement(KwtWaybillOrder waybillOrder, int type) {
        //运载信息
        List<WaybillOrderLoadingVO> loadLoading = new ArrayList<>();
        //单位数据字典
        Map<String, SysDictResDto> unitType = remoteSystemService.queryDictMapByType(DictTypeEnum.UNIT_TYPE.getType());
        //装载信息
        List<KwtWaybillOrderTicket> loading = ticketMapper.findWaybillOrderTicket(waybillOrder.getId(), null, type);
        if (CollectionUtils.isNotEmpty(loading)) {
            loading.forEach(e -> {
                SysDictResDto sysDict = unitType != null ? unitType.get(e.getUnit()) : null;
                WaybillOrderLoadingVO loadingVo = new WaybillOrderLoadingVO(e.getUnit(), sysDict != null ? sysDict.getLabel() : null, e.getAmount());
                loadingVo.setMain(waybillOrder.getUnit().equals(e.getUnit()) ? true : false);
                loadLoading.add(loadingVo);
            });
        }
        return loadLoading;
    }

    /**
     * 单证信息
     * @param subtask 运单-子单
     * @param wAddressId 运单地址ID
     * @return 运载信息
     */
    public List<WaybillOrderLoadingVO> agreementV1(KwtWaybillOrderSubtask subtask, Long wAddressId) {
        //运载信息
        List<WaybillOrderLoadingVO> loadLoading = new ArrayList<>();
        //单位数据字典
        Map<String, SysDictResDto> unitType = remoteSystemService.queryDictMapByType(DictTypeEnum.UNIT_TYPE.getType());
        //装载信息
        List<KwtWaybillOrderTicket> loading = ticketMapper.findWaybillOrderTicketV3(wAddressId, null);
        if (CollectionUtils.isNotEmpty(loading)) {
            loading.forEach(e -> {
                SysDictResDto sysDict = unitType != null ? unitType.get(e.getUnit()) : null;
                WaybillOrderLoadingVO loadingVo = new WaybillOrderLoadingVO(e.getUnit(), sysDict != null ? sysDict.getLabel() : null, e.getAmount());
                loadingVo.setMain(subtask.getUnit().equals(e.getUnit()) ? true : false);
                loadLoading.add(loadingVo);
            });
        }
        return loadLoading;
    }

    /**
     * 计算地址下所有的地址
     * @param lAddressId 地址ID
     * @return 地址ID
     */
    public List<Long> getLAddressIds(Long lAddressId) {
        LambdaQueryWrapper<KwtLogisticsOrderAddress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwtLogisticsOrderAddress::getPAddressId, lAddressId);
        wrapper.eq(KwtLogisticsOrderAddress::getDelFlag, Global.NO);
        List<KwtLogisticsOrderAddress> list = logisticsOrderAddressMapper.selectList(wrapper);
        List<Long> lAddressIds = list.stream().map(KwtLogisticsOrderAddress::getId).toList();
        if (CollectionUtils.isNotEmpty(lAddressIds)) {
            for (Long lAddressId1:lAddressIds) {
                List<Long> lAddressIds1 = getLAddressIds(lAddressId1);
                if (CollectionUtils.isNotEmpty(lAddressIds1)) {
                    lAddressIds.addAll(lAddressIds1);
                }
            }
        }
        return lAddressIds;
    }

    /**
     * 计算地址下所有的运单榜单上的运量
     * @param lAddressId 地址ID
     * @return 运载量
     */
    public BigDecimal getAmount(Long lAddressId, String unit, int type) {
        List<Long> lAddressIds = new ArrayList<>(){{add(lAddressId);}};
        lAddressIds.addAll(getLAddressIds(lAddressId));
        Map<String, Object> queryParams = new HashMap<>(NumberConstant.SIXTEEN);
        queryParams.put("lAddressIds", lAddressIds);
        queryParams.put("unit", unit);
        queryParams.put("type", type);
        queryParams.put("passStatus", Global.NUMERICAL_ONE);
        WaybillCountVo loadCount = waybillOrderV1Mapper.findTicketAmountByAddress(queryParams);
        return loadCount.getAmount();
    }

}
