package com.sckw.payment.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.StringTimeUtil;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.payment.dao.KwpSettlementLogisticsMapper;
import com.sckw.payment.model.KwpSettlementLogistics;
import com.sckw.payment.model.constant.LogisticsUnitType;
import com.sckw.payment.model.constant.SettlementEnum;
import com.sckw.payment.model.constant.SettlementOrderTypeEnum;
import com.sckw.payment.model.constant.TradingEnum;
import com.sckw.payment.model.dto.*;
import com.sckw.payment.model.vo.SettlementVo;
import com.sckw.payment.model.vo.req.SettlementReq;
import com.sckw.payment.model.vo.res.SettlementLogisticsStatusCountVo;
import com.sckw.payment.model.vo.res.SettlementLogisticsSumVo;
import com.sckw.payment.utils.CommonValidator;
import com.sckw.payment.utils.PageMoreRes;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
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.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Aick Spt
 * @date 2023-07-10 16:38:36
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class KwpSettlementLogisticsService {
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;
    private final KwpSettlementLogisticsMapper settlementLogisticsMapper;
    @Resource
    private KwpSettlementWalletService kwpSettlementWalletService;
    @Resource
    private KwpSettlementOfflineService kwpSettlementOfflineService;

    private void changeDict(List<? extends ISettlement> list) {
        //字典等数据转换
        Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
        for (ISettlement iSettlement : list) {
            String trading = iSettlement.getTrading();
            SysDictResDto sysDictResDto = dictResDtoMap.get(trading);
            if (Objects.nonNull(sysDictResDto)) {
                iSettlement.setTradingLabel(sysDictResDto.getLabel());
            }
            iSettlement.setStatusLabel(SettlementEnum.getStatusDesc(iSettlement.getStatus()));
        }
    }

    public void save(KwpSettlementLogistics settlementLogistics) {
        settlementLogisticsMapper.insert(settlementLogistics);
    }

    /**
     * 运费收款-物流订单各状态列表总数
     *
     * @author Aick Spt
     * @date 2023-07-24 16:21
     */
    public List<TableTop> getCountListCollection(SettlementReq settlementReq) {
        settlementReq.setUnitType(LogisticsUnitType.SHIPPER);
        settlementReq.setUnitTypeTwo(LogisticsUnitType.CARRIER);
        return getCountList(settlementReq);
    }

    /**
     * 运费付款-物流订单各状态列表总数
     *
     * @author Aick Spt
     * @date 2023-07-24 16:23
     */
    public List<TableTop> getCountListPayment(SettlementReq settlementReq) {
        settlementReq.setUnitType(LogisticsUnitType.CARRIER);
        settlementReq.setUnitTypeTwo(LogisticsUnitType.SHIPPER);
        return getCountList(settlementReq);
    }

    /**
     * 运费收款-物流订单列表
     *
     * @author Aick Spt
     * @date 2023-07-24 16:21
     */
    public PageMoreRes<SettlementLogisticsDto> pageSelectCollection(SettlementReq settlementReq) {
        settlementReq.setUnitType(LogisticsUnitType.SHIPPER);
        settlementReq.setUnitTypeTwo(LogisticsUnitType.CARRIER);
        return pageSelect(settlementReq);
    }

    /**
     * 运费付款-物流订单列表
     *
     * @author Aick Spt
     * @date 2023-07-24 16:23
     */
    public PageMoreRes<SettlementLogisticsDto> pageSelectPayment(SettlementReq settlementReq) {
        settlementReq.setUnitType(LogisticsUnitType.CARRIER);
        settlementReq.setUnitTypeTwo(LogisticsUnitType.SHIPPER);
        return pageSelect(settlementReq);
    }

    /**
     * 查询贸易结算详情
     *
     * @param id       结算单id
     * @param unitType 企业类型
     * @return
     */
    public SettlementDetailDto<SettlementLogisticsDto, SettlementVo> queryDetail(Long id, Integer unitType) {
        SettlementLogisticsDto settlementLogisticsDto = settlementLogisticsMapper.selectDetail(id, unitType);
        if (Objects.isNull(settlementLogisticsDto)) {
            throw new BusinessException("结算单不存在");
        }
        Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
        String trading = settlementLogisticsDto.getTrading();
        SysDictResDto sysDictResDto = dictResDtoMap.get(trading);
        if (Objects.nonNull(sysDictResDto)) {
            settlementLogisticsDto.setTradingLabel(sysDictResDto.getLabel());
        }
        settlementLogisticsDto.setPercentage(settlementLogisticsDto.changePercentage(settlementLogisticsDto.getActualPrice(), settlementLogisticsDto.getTotalPrice()));
        settlementLogisticsDto.setStatusLabel(SettlementEnum.getStatusDesc(settlementLogisticsDto.getStatus()));
        Integer payType = TradingEnum.getPrefix(trading);
        List<SettlementVo> settlementVoList = new ArrayList<>();
        if (Objects.nonNull(payType)) {
            if (payType == TradingEnum.OFFLINE_PAY.getStatus()) {
                settlementVoList = kwpSettlementOfflineService.queryList(id, SettlementOrderTypeEnum.LOGISTICS.getStatus(), payType);
            } else {
                settlementVoList = kwpSettlementWalletService.queryList(id, SettlementOrderTypeEnum.LOGISTICS.getStatus(), payType);
            }
        }
        return new SettlementDetailDto<>(settlementLogisticsDto, settlementVoList);
    }

    /**
     * 运费收款-物流订单详情
     *
     * @author Aick Spt
     * @date 2023-07-24 16:22
     */
    public SettlementLogisticsDto detailCollection(Long id) {
        if (id == null) {
            throw new BusinessException("结算单ID必传");
        }
        return detail(id, LogisticsUnitType.SHIPPER, LogisticsUnitType.CARRIER);
    }

    /**
     * 运费付款-物流订单详情
     *
     * @author Aick Spt
     * @date 2023-07-24 16:24
     */
    public SettlementLogisticsDto detailPayment(Long id) {
        return detail(id, LogisticsUnitType.CARRIER, LogisticsUnitType.SHIPPER);
    }

    /**
     * 根据条件查物流结算订单-导出
     *
     * @author Aick Spt
     * @date 2023-07-21 16:16
     */
    public List<SettlementLogisticsDto> selectList(SettlementReq settlementReq) {
        validSettlementReq(settlementReq);
        List<SettlementLogisticsDto> settlementLogisticsDtos = settlementLogisticsMapper.selectLogisticsList(settlementReq, settlementReq.getIdList());
        changeDict(settlementLogisticsDtos);
        for (SettlementLogisticsDto settlementLogisticsDto : settlementLogisticsDtos) {
            UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(settlementLogisticsDto.getUpdateBy());
            settlementLogisticsDto.setUpdateByLabel(Objects.nonNull(userCacheResDto) ? userCacheResDto.getName() : "");
        }
        return settlementLogisticsDtos;
    }

    /**
     * 验证过滤信息
     *
     * @param settlementReq
     * @author Aick Spt
     * @date 2023-08-01 10:45
     */
    private void validSettlementReq(SettlementReq settlementReq) {
        //判断时间是否成对
        CommonValidator.isValidCoexisting(settlementReq.getStartCreateTime(), settlementReq.getEndCreateTime(), "");
        CommonValidator.isValidCoexisting(settlementReq.getStartReceiptTime(), settlementReq.getEndReceiptTime(), "预计付款开始和结束时间");
        //补全时间信息
        if (StringUtils.isNotBlank(settlementReq.getStartCreateTime())) {
            settlementReq.setStartCreateTime(StringTimeUtil.fillStart(settlementReq.getStartCreateTime()));
        }
        if (StringUtils.isNotBlank(settlementReq.getEndCreateTime())) {
            settlementReq.setEndCreateTime(StringTimeUtil.fillEnd(settlementReq.getEndCreateTime()));
        }
        if (StringUtils.isNotBlank(settlementReq.getStartReceiptTime())) {
            settlementReq.setStartCreateTime(StringTimeUtil.fillStart(settlementReq.getStartReceiptTime()));
        }
        if (StringUtils.isNotBlank(settlementReq.getEndReceiptTime())) {
            settlementReq.setEndCreateTime(StringTimeUtil.fillEnd(settlementReq.getEndReceiptTime()));
        }
        //加上当前登录者顶级企业id用于过滤数据
        settlementReq.setEntId(LoginUserHolder.getEntId());
    }

    /**
     * 分页查询结算物流(运费)相关订单数据，并查询出对应合计
     *
     * @author Aick Spt
     * @date 2023-08-03 10:29
     */
    private PageMoreRes<SettlementLogisticsDto> pageSelect(SettlementReq settlementReq) {
        //验证相关参数
        validSettlementReq(settlementReq);
        //加上当前登录者顶级企业id用于过滤数据
        settlementReq.setEntId(LoginUserHolder.getEntId());
        //添加默认分页数据
        PageHelper.startPage(settlementReq.getPage(), settlementReq.getPageSize());
        //查询分页数据
        List<SettlementLogisticsDto> kwpLedgerLogisticsList = settlementLogisticsMapper.pageSelect(settlementReq);
        //查询同样条件下的合计
        SettlementLogisticsSumVo settlementLogisticsSum = settlementLogisticsMapper.selectSum(settlementReq);
        PageInfo<SettlementLogisticsDto> pageInfo = new PageInfo<>(kwpLedgerLogisticsList);

        Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
        for (SettlementLogisticsDto entity : kwpLedgerLogisticsList) {
            SysDictResDto sysDictResDto = dictResDtoMap.get(entity.getTrading());
            if (Objects.nonNull(sysDictResDto)) {
                entity.setTradingLabel(sysDictResDto.getLabel());
            }
            setDetailDesc(entity);
        }

        return new PageMoreRes<>(pageInfo, settlementLogisticsSum);
    }

    /**
     * 根据条件获取列表头部汇总数据
     *
     * @author Aick Spt
     * @date 2023-08-03 10:44
     */
    public List<TableTop> getCountList(SettlementReq settlementReq) {
        validSettlementReq(settlementReq);
        SettlementLogisticsStatusCountVo settlementLogisticsStatusCountVos = new SettlementLogisticsStatusCountVo();

        //加上当前登录者顶级企业id用于过滤数据
        settlementReq.setEntId(LoginUserHolder.getEntId());

        List<TableTop> tableTops = new ArrayList<>();
        TableTop tableTop = new TableTop();
        //总
        settlementReq.setStatus(SettlementEnum.ALL.getStatus());
        settlementLogisticsStatusCountVos.setAllCount(settlementLogisticsMapper.getCountList(settlementReq));
        tableTop.setName("全部").setValue(settlementReq.getStatus()).setTotal(Math.toIntExact(settlementLogisticsStatusCountVos.getAllCount()));
        tableTops.add(tableTop);

        //待结算
        settlementReq.setStatus(SettlementEnum.WAITING_PAYMENT.getStatus());
//        settlementLogisticsStatusCountVos.setWaitingPaymentCount(settlementLogisticsMapper.getCountList(settlementReq));
        Long a = settlementLogisticsMapper.getCountList(settlementReq);
        settlementLogisticsStatusCountVos.setWaitingPaymentCount(a);
        TableTop tableTop1 = new TableTop();
        tableTop1.setName("待结算").setValue(SettlementEnum.WAITING_PAYMENT.getStatus()).setTotal(Math.toIntExact(a));
        tableTops.add(tableTop1);

        //部分结算
        settlementReq.setStatus(SettlementEnum.PARTIAL_PAYMENT.getStatus());
        settlementLogisticsStatusCountVos.setPartialPaymentCount(settlementLogisticsMapper.getCountList(settlementReq));
        TableTop tableTop2 = new TableTop();
        tableTop2.setName("部分结算").setValue(SettlementEnum.PARTIAL_PAYMENT.getStatus()).setTotal(Math.toIntExact(settlementLogisticsStatusCountVos.getPartialPaymentCount()));
        tableTops.add(tableTop2);

        //全部结算
        settlementReq.setStatus(SettlementEnum.ALL_PAYMENT.getStatus());
        settlementLogisticsStatusCountVos.setAllPaymentCount(settlementLogisticsMapper.getCountList(settlementReq));
        TableTop tableTop3 = new TableTop();
        tableTop3.setName("全部结算").setValue(SettlementEnum.ALL_PAYMENT.getStatus()).setTotal(Math.toIntExact(settlementLogisticsStatusCountVos.getAllPaymentCount()));
        tableTops.add(tableTop3);

        return tableTops;
    }

    /**
     * 运费-物流订单详情
     *
     * @author Aick Spt
     * @date 2023-08-07 10:14
     */
    public SettlementLogisticsDto detail(Long id, Integer unitType, Integer unitTypeTwo) {
        SettlementLogisticsDto settlementLogisticsDto = settlementLogisticsMapper.detail(id, unitType, unitTypeTwo);
        if (settlementLogisticsDto == null) {
            throw new BusinessException("查无数据");
        }
        //
        Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
        SysDictResDto sysDictResDto = dictResDtoMap.get(settlementLogisticsDto.getTrading());
        if (Objects.nonNull(sysDictResDto)) {
            settlementLogisticsDto.setTradingLabel(sysDictResDto.getLabel());
        }
        setDetailDesc(settlementLogisticsDto);
        return settlementLogisticsDto;
    }

    /**
     * 根据id查询结算单关联的企业信息
     *
     * @param id 结算单id
     * @return
     */
    public List<LedgerUnitDto> getListById(Long id) {
        return settlementLogisticsMapper.getListById(id);
    }


    /**
     * 增加 创建、更新人名称及字段
     *
     * @author Aick Spt
     * @date 2023-08-07 10:14
     */
    private void setDetailDesc(SettlementLogisticsDto settlementLogisticsDto) {
        //结算比例
        settlementLogisticsDto.setPercentage(settlementLogisticsDto.changePercentage(settlementLogisticsDto.getActualPrice(), settlementLogisticsDto.getTotalPrice()));

        //更改创建、更新人名称及字段
        settlementLogisticsDto.setStatusLabel(SettlementEnum.getStatusDesc(settlementLogisticsDto.getStatus()));
        if (settlementLogisticsDto.getTotalPrice() != null) {
            if (settlementLogisticsDto.getActualPrice() != null) {
                settlementLogisticsDto.setWaitPrice(settlementLogisticsDto.getTotalPrice().subtract(settlementLogisticsDto.getActualPrice()));
            } else {
                settlementLogisticsDto.setWaitPrice(settlementLogisticsDto.getTotalPrice());
            }
        } else {
            settlementLogisticsDto.setWaitPrice(new BigDecimal(0));
        }
        //"创建人名称"
        settlementLogisticsDto.setCreateByLabel("创建人名称");
        //"更新人名称"
        settlementLogisticsDto.setUpdateByLabel("更新人名称");

        Long createBy = settlementLogisticsDto.getCreateBy();
        Long updateBy = settlementLogisticsDto.getUpdateBy();
        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(createBy);
        if (Objects.nonNull(userCacheResDto)) {
            settlementLogisticsDto.setCreateByLabel(userCacheResDto.getName());
        }
        UserCacheResDto userCacheResDto2 = remoteSystemService.queryUserCacheById(updateBy);
        if (Objects.nonNull(userCacheResDto2)) {
            //写入对应数据
            settlementLogisticsDto.setUpdateByLabel(userCacheResDto2.getName());
        }
    }

    /**
     * @param entId     企业id 托运方
     * @param entTarget 另一方企业id 承运方
     * @return
     */
    public List<String> checkOrder(Long entId, Long entTarget) {
        return settlementLogisticsMapper.selectJoin(entId, entTarget);
    }

    /**
     * @param entId    顶级企业id
     * @param cur      当月/周
     * @param pre      上月/周
     * @param unitType 企业类型 2-销售 1-采购
     */
    public List<MoneyType> moneySum(Long entId, List<LocalDateTime> cur, List<LocalDateTime> pre, Integer unitType) {
        return settlementLogisticsMapper.sumMoneyType(entId, cur, pre, unitType);

    }
}
