package com.sckw.payment.service.operateService;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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.page.PageRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringTimeUtil;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.payment.dao.KwpLedgerLogisticsMapper;
import com.sckw.payment.model.KwpLedgerLogistics;
import com.sckw.payment.model.KwpLedgerLogisticsOrder;
import com.sckw.payment.model.constant.LedgerEnum;
import com.sckw.payment.model.constant.LogisticsUnitType;
import com.sckw.payment.model.dto.ILedger;
import com.sckw.payment.model.vo.LedgerLogistics;
import com.sckw.payment.model.vo.req.LedgerListReq;
import com.sckw.payment.model.vo.req.LogisticsReq;
import com.sckw.payment.model.vo.res.LedgerLogisticsDetailVo;
import com.sckw.payment.service.AbsLedger;
import com.sckw.payment.service.KwpLedgerLogisticsOrderService;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.RemoteUserService;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import com.sckw.transport.api.dubbo.TransportRemoteService;
import com.sckw.transport.api.model.dto.AcceptCarriageLogisticsOrderDto;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xucaiqin
 * @date 2023-07-10 16:38:36
 */
@Service
@Slf4j
public class LedgerLogisticsService extends AbsLedger {
    @Resource
    private KwpLedgerLogisticsOrderService logisticsOrderService;
    @Resource
    private KwpLedgerLogisticsMapper logisticsMapper;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private TransportRemoteService transportRemoteService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteUserService remoteUserService;

    private void changeDict(List<? extends ILedger> list) {
        List<SysDictResDto> taxRateDict = remoteSystemService.queryDictByType(DictTypeEnum.TAX_RATE.getType());
        Map<String, String> taxRateMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> tradingMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);

        if (!CollectionUtils.isEmpty(taxRateDict)) {
            taxRateMap = taxRateDict.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (a, b) -> a));
        }
        List<SysDictResDto> tradingDict = remoteSystemService.queryDictByType(DictTypeEnum.TRADE_TYPE.getType());
        if (!CollectionUtils.isEmpty(tradingDict)) {
            tradingMap = tradingDict.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (a, b) -> a));
        }
        for (ILedger logisticsDto : list) {
            String trading = logisticsDto.getTrading();
            logisticsDto.setTradingLabel(tradingMap.get(trading));
            Integer taxRate = logisticsDto.getTaxRate();
            logisticsDto.setTaxRateLabel(taxRateMap.get(String.valueOf(taxRate)));

            logisticsDto.setStatusLabel(LedgerEnum.getDesc(logisticsDto.getStatus()));

            UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(logisticsDto.getCreateBy());
            if (Objects.nonNull(userCacheResDto)) {
                logisticsDto.setCreateByName(userCacheResDto.getName());
            }
        }
    }

    private void fillPara(LogisticsReq logisticsReq) {
        if (StringUtils.isNotBlank(logisticsReq.getStartCreateTime())) {
            logisticsReq.setStartCreateTime(StringTimeUtil.fillStart(logisticsReq.getStartCreateTime()));
        }
        if (StringUtils.isNotBlank(logisticsReq.getEndCreateTime())) {
            logisticsReq.setEndCreateTime(StringTimeUtil.fillEnd(logisticsReq.getEndCreateTime()));
        }
    }

    /**
     * 托运方物流对账单列表查询
     *
     * @param logisticsReq
     * @return 托运方对账订单分页数据
     */
    public PageRes<LedgerLogistics> list(LogisticsReq logisticsReq,boolean export) {
        fillPara(logisticsReq);
        logisticsReq.setUnitType(LogisticsUnitType.SHIPPER);
        logisticsReq.setUnitTypeTwo(LogisticsUnitType.CARRIER);
        if(!export){
            PageHelper.startPage(logisticsReq.getPage(), logisticsReq.getPageSize());
        }

        //新增客户经理权限过滤
        List<Long> authEntIdList = LoginUserHolder.getAuthEntIdList();
        if (CollectionUtils.isEmpty(authEntIdList)){
            List<Long> ids = remoteUserService.findEnterpriseIdsByUserIdIsMain(LoginUserHolder.getUserId());
            if (CollectionUtils.isEmpty(ids)){
                return new PageRes<>(new ArrayList<>());
            }
            authEntIdList.addAll(ids);
        }

        List<LedgerLogistics> kwpLedgerLogisticsList = logisticsMapper.list(logisticsReq,authEntIdList);
        PageInfo<LedgerLogistics> ledgerShipperDtoPageInfo = new PageInfo<>(kwpLedgerLogisticsList);
        //字典转换
        if (!CollectionUtils.isEmpty(kwpLedgerLogisticsList)) {
            changeDict(ledgerShipperDtoPageInfo.getList());
            return new PageRes<>(ledgerShipperDtoPageInfo);
        }
        return new PageRes<>(ledgerShipperDtoPageInfo);
    }

    public PageRes<AcceptCarriageLogisticsOrderDto> orderList(LedgerListReq ledgerListReq) {
        PageHelper.startPage(ledgerListReq.getPage(), ledgerListReq.getPageSize());
        List<KwpLedgerLogisticsOrder> kwpLedgerLogisticsOrders = logisticsOrderService.queryList(ledgerListReq.getIdLong());
        if (CollectionUtils.isEmpty(kwpLedgerLogisticsOrders)) {
            return new PageRes<>();
        }
        PageInfo<KwpLedgerLogisticsOrder> pageInfo = new PageInfo<>(kwpLedgerLogisticsOrders);
        List<AcceptCarriageLogisticsOrderDto> acceptCarriageOrderList = transportRemoteService.getAcceptCarriageOrderList(kwpLedgerLogisticsOrders.stream().map(a -> String.valueOf(a.getLOrderId())).toList());
        return PageRes.build(pageInfo, acceptCarriageOrderList);
    }


    /**
     * 按类型统计表头的数据
     * 1-托运方 2-承运方
     *
     * @param logisticsReq 查询参数
     * @return 统计数据
     */
    public List<TableTop> orderCount(LogisticsReq logisticsReq) {
        /*统计数据转换*/
        List<TableTop> res = new ArrayList<>();

        //新增客户经理权限过滤
        List<Long> authEntIdList = LoginUserHolder.getAuthEntIdList();
        if (CollectionUtils.isEmpty(authEntIdList)){
            List<Long> ids = remoteUserService.findEnterpriseIdsByUserIdIsMain(LoginUserHolder.getUserId());
            if (CollectionUtils.isEmpty(ids)){
                TableTop ledgerCountVo;
                for (LedgerEnum value : LedgerEnum.values()) {
                    ledgerCountVo = new TableTop();
                    ledgerCountVo.setTotal(NumberConstant.ZERO);
                    ledgerCountVo.setName(value.getDesc());
                    ledgerCountVo.setValue(value.getStatus());
                    res.add(ledgerCountVo);
                }
                return res;
            }
            authEntIdList.addAll(ids);
        }

        Map<String, Long> map = logisticsMapper.countOrder2(logisticsReq,authEntIdList);
        TableTop ledgerCountVo;
        for (LedgerEnum value : LedgerEnum.values()) {
            ledgerCountVo = new TableTop();
            ledgerCountVo.setTotal(Math.toIntExact(map.get(value.getLabel())));
            ledgerCountVo.setName(value.getDesc());
            ledgerCountVo.setValue(value.getStatus());
            res.add(ledgerCountVo);
        }
        return res;
    }

    /**
     * 查询物流对账单
     *
     * @param ids 对账单id列表
     * @return 物流对账单列表
     */
    public List<LedgerLogistics> selectList(List<Long> ids) {
        List<LedgerLogistics> ledgerLogisticsDto = logisticsMapper.selectIds(ids);
        changeDict(ledgerLogisticsDto);
        return ledgerLogisticsDto;
    }

    /**
     * 查询物流对账单详情
     *
     * @param id 物流对账单id
     * @return
     */
    public LedgerLogisticsDetailVo queryDetail(Long id) {
        KwpLedgerLogistics kwpLedgerLogistics = logisticsMapper.selectById(id);
        orderCheck(kwpLedgerLogistics);
        return getLedgerLogisticsDetailVo(kwpLedgerLogistics);
    }

    /**
     * 转换物流对账单详情数据
     *
     * @param ledgerLogisticsDto
     * @return
     */
    private LedgerLogisticsDetailVo getLedgerLogisticsDetailVo(KwpLedgerLogistics ledgerLogisticsDto) {
        /*获取物流对账单关联的物流订单*/
        List<KwpLedgerLogisticsOrder> kwpLedgerLogisticsOrders = logisticsOrderService.queryList(ledgerLogisticsDto.getId());
        LedgerLogisticsDetailVo ledgerLogisticsDetailVo = new LedgerLogisticsDetailVo();
        SysDictResDto trading = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TRADE_TYPE.getType(), ledgerLogisticsDto.getTrading());
        SysDictResDto taxRate = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TRADE_TYPE.getType(), String.valueOf(ledgerLogisticsDto.getTaxRate()));

        ledgerLogisticsDetailVo.setId(ledgerLogisticsDto.getId());
        ledgerLogisticsDetailVo.setLLedgerNo(ledgerLogisticsDto.getLLedgerNo());
        ledgerLogisticsDetailVo.setName(ledgerLogisticsDto.getName());
        ledgerLogisticsDetailVo.setTrading(ledgerLogisticsDto.getTrading());
        ledgerLogisticsDetailVo.setTradingLabel(Objects.nonNull(trading) ? trading.getLabel() : "");

        ledgerLogisticsDetailVo.setTaxRate(ledgerLogisticsDto.getTaxRate());
        ledgerLogisticsDetailVo.setTaxRateLabel(Objects.nonNull(taxRate) ? taxRate.getLabel() : "");
        ledgerLogisticsDetailVo.setTotalPrice(ledgerLogisticsDto.getTotalPrice());
        ledgerLogisticsDetailVo.setSettlePrice(ledgerLogisticsDto.getSettlePrice());
        ledgerLogisticsDetailVo.setActualPrice(ledgerLogisticsDto.getActualPrice());
        ledgerLogisticsDetailVo.setStartTime(ledgerLogisticsDto.getStartTime());
        ledgerLogisticsDetailVo.setEndTime(ledgerLogisticsDto.getEndTime());
        ledgerLogisticsDetailVo.setRemark(ledgerLogisticsDto.getRemark());
        /*查询物流订单详情*/
        if (!CollectionUtils.isEmpty(kwpLedgerLogisticsOrders)) {
            List<AcceptCarriageLogisticsOrderDto> acceptCarriageOrderList = transportRemoteService.getAcceptCarriageOrderList(kwpLedgerLogisticsOrders.stream().map(a -> Long.toString(a.getLOrderId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(acceptCarriageOrderList)) {
                ledgerLogisticsDetailVo.setOrderList(new ArrayList<>());
            } else {
                ledgerLogisticsDetailVo.setOrderList(acceptCarriageOrderList);
            }
        }
        return ledgerLogisticsDetailVo;
    }
}
