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.page.PageRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.payment.dao.KwpSettlementTradeMapper;
import com.sckw.payment.model.KwpSettlementTrade;
import com.sckw.payment.model.constant.SettlementEnum;
import com.sckw.payment.model.constant.SettlementOrderTypeEnum;
import com.sckw.payment.model.constant.TradeUnitType;
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.SettlementTradeReq;
import com.sckw.payment.model.vo.res.SettlementSumVo;
import com.sckw.payment.model.vo.res.SettlementTradeVo;
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 org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 贸易结算
 *
 * @author xucaiqin
 * @date 2023-07-10 16:38:36
 */
@Service
@RequiredArgsConstructor
public class KwpSettlementTradeService {
    private final KwpSettlementTradeMapper settlementTradeMapper;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;
    @Resource
    private KwpSettlementWalletService kwpSettlementWalletService;
    @Resource
    private KwpSettlementOfflineService kwpSettlementOfflineService;


    /**
     * 查询结算单详情
     *
     * @param id       结算单id
     * @param unitType 企业单位类型
     * @return
     */
    public SettlementTradeDto getById(Long id, Integer unitType) {
        return settlementTradeMapper.getById(id, unitType);
    }

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

    /**
     * 保存结算单
     *
     * @param kwpSettlementTrade 结算单
     */
    public void save(KwpSettlementTrade kwpSettlementTrade) {
        settlementTradeMapper.insert(kwpSettlementTrade);
    }

    /**
     * 字典转换
     *
     * @param list 结算单列表数据
     */
    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()));
        }
    }

    /**
     * 分页查询结算单数据
     *
     * @param settlementReq 结算单查询参数
     * @return
     */
    public PageRes<ISettlement> pageListCollection(SettlementTradeReq settlementReq) {
        settlementReq.setEntId(LoginUserHolder.getEntId());
        PageHelper.startPage(settlementReq.getPage(), settlementReq.getPageSize());
        List<SettlementTradeDto> kwpLedgerLogisticsList = settlementTradeMapper.pageSelect(settlementReq);
        PageInfo<ISettlement> settlementPageInfo = new PageInfo<>(kwpLedgerLogisticsList);
        if (!CollectionUtils.isEmpty(kwpLedgerLogisticsList)) {
            //根据企业类型转换对应的数据
            if (Objects.equals(settlementReq.getUnitType(), TradeUnitType.PURCHASE)) {
                List<ISettlement> res = new ArrayList<>();
                SettlementPurchaseDto settlementSellDto;
                for (SettlementTradeDto settlementTradeDto : kwpLedgerLogisticsList) {
                    settlementSellDto = new SettlementPurchaseDto();
                    BeanUtils.copyProperties(settlementTradeDto, settlementSellDto);
                    settlementSellDto.setActualPrice(settlementSellDto.changePrice(settlementTradeDto.getActualPrice()));
                    settlementSellDto.setTotalPrice(settlementSellDto.changePrice(settlementTradeDto.getTotalPrice()));
                    settlementSellDto.setWaitPrice(settlementSellDto.changePrice(settlementTradeDto.getWaitPrice()));
                    UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(settlementTradeDto.getUpdateBy());
                    settlementSellDto.setUpdateByLabel(Objects.nonNull(userCacheResDto) ? userCacheResDto.getName() : "");
                    settlementSellDto.setPercentage(settlementSellDto.changePercentage(settlementTradeDto.getActualPrice(), settlementTradeDto.getTotalPrice()));
                    res.add(settlementSellDto);
                }
                changeDict(res);
                return new PageRes<>(settlementPageInfo, res);
            }
            //根据企业类型转换对应的数据
            if (Objects.equals(settlementReq.getUnitType(), TradeUnitType.SELL)) {
                List<ISettlement> res = new ArrayList<>();
                SettlementSellDto settlementSellDto;
                for (SettlementTradeDto settlementTradeDto : kwpLedgerLogisticsList) {
                    settlementSellDto = new SettlementSellDto();
                    BeanUtils.copyProperties(settlementTradeDto, settlementSellDto);
                    settlementSellDto.setActualPrice(settlementSellDto.changePrice(settlementTradeDto.getActualPrice()));
                    settlementSellDto.setTotalPrice(settlementSellDto.changePrice(settlementTradeDto.getTotalPrice()));
                    settlementSellDto.setWaitPrice(settlementSellDto.changePrice(settlementTradeDto.getWaitPrice()));
                    UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(settlementTradeDto.getUpdateBy());
                    settlementSellDto.setUpdateByLabel(Objects.nonNull(userCacheResDto) ? userCacheResDto.getName() : "");
                    settlementSellDto.setPercentage(settlementSellDto.changePercentage(settlementTradeDto.getActualPrice(), settlementTradeDto.getTotalPrice()));
                    res.add(settlementSellDto);
                }
                changeDict(res);
                return new PageRes<>(settlementPageInfo, res);
            }
        }
        return new PageRes<>(settlementPageInfo);
    }

    /**
     * 统计列表的表头数据
     *
     * @param settlementReq 结算单查询参数
     * @return
     */
    public List<TableTop> getCount(SettlementTradeReq settlementReq) {
        Map<String, Long> stringIntegerMap = settlementTradeMapper.countOrder(settlementReq);
        List<TableTop> res = new ArrayList<>(4);
        for (SettlementEnum value : SettlementEnum.values()) {
            TableTop tableTop = new TableTop();
            tableTop.setName(value.getDesc());
            tableTop.setValue(value.getStatus());
            tableTop.setTotal(Math.toIntExact(stringIntegerMap.get(value.getLabel())));
            res.add(tableTop);
        }
        return res;
    }

    /**
     * 表尾统计数据
     *
     * @param settlementReq 结算单查询参数
     * @return
     */
    public SettlementSumVo getCountListCollection(SettlementTradeReq settlementReq) {
        return settlementTradeMapper.sumMoney(settlementReq);
    }

    /**
     * 列表查询
     *
     * @param ids      结算单id列表
     * @param unitType 企业单位类型
     * @return
     */
    public List<ISettlement> selectList(List<Long> ids, int unitType) {
        List<SettlementTradeDto> kwpSettlementTrades = settlementTradeMapper.selectByIds(ids, unitType);
        if (!CollectionUtils.isEmpty(kwpSettlementTrades)) {
            //根据企业类型进行对应的数据
            if (unitType == TradeUnitType.PURCHASE) {
                List<SettlementPurchaseDto> list = kwpSettlementTrades.stream().map(a -> {
                    SettlementPurchaseDto settlementSellDto = new SettlementPurchaseDto();
                    BeanUtils.copyProperties(a, settlementSellDto);
                    settlementSellDto.setActualPrice(settlementSellDto.changePrice(a.getActualPrice()));
                    settlementSellDto.setTotalPrice(settlementSellDto.changePrice(a.getTotalPrice()));
                    settlementSellDto.setWaitPrice(settlementSellDto.changePrice(a.getWaitPrice()));
                    return settlementSellDto;
                }).toList();
                List<ISettlement> ledgerShipperDto = new ArrayList<>(list);
                changeDict(ledgerShipperDto);
                return ledgerShipperDto;
            }
            if (unitType == TradeUnitType.SELL) {
                //数据转换
                List<SettlementSellDto> list = kwpSettlementTrades.stream().map(a -> {
                    SettlementSellDto settlementSellDto = new SettlementSellDto();
                    BeanUtils.copyProperties(a, settlementSellDto);
                    settlementSellDto.setActualPrice(settlementSellDto.changePrice(a.getActualPrice()));
                    settlementSellDto.setTotalPrice(settlementSellDto.changePrice(a.getTotalPrice()));
                    settlementSellDto.setWaitPrice(settlementSellDto.changePrice(a.getWaitPrice()));
                    return settlementSellDto;
                }).toList();
                List<ISettlement> ledgerShipperDto = new ArrayList<>(list);
                changeDict(ledgerShipperDto);
                return ledgerShipperDto;
            }
        }
        return new ArrayList<>();
    }


    /**
     * 更新对账单
     *
     * @param kwpSettlementTrade 对账单数据
     */
    public void updateById(KwpSettlementTrade kwpSettlementTrade) {
        settlementTradeMapper.updateById(kwpSettlementTrade);
    }

    /**
     * @param entId     企业id 采购方
     * @param entTarget 另一方企业id 销售方
     * @return
     */
    public List<String> checkOrder(Long entId, Long entTarget) {
        return settlementTradeMapper.selectJoin(entId, entTarget);
    }

    /**
     * 查询贸易结算详情
     *
     * @param id       结算单id
     * @param unitType 企业类型
     * @return
     */
    public SettlementDetailDto<SettlementTradeDto, SettlementVo> queryDetail(Long id, Integer unitType) {
        SettlementTradeDto settlementTradeDto = settlementTradeMapper.selectDetail(id, unitType);
        if (Objects.isNull(settlementTradeDto)) {
            throw new BusinessException("结算单不存在");
        }
        Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
        String trading = settlementTradeDto.getTrading();
        SysDictResDto sysDictResDto = dictResDtoMap.get(trading);
        if (Objects.nonNull(sysDictResDto)) {
            settlementTradeDto.setTradingLabel(sysDictResDto.getLabel());
        }
        settlementTradeDto.setPercentage(settlementTradeDto.changePercentage(settlementTradeDto.getActualPrice(), settlementTradeDto.getTotalPrice()));
        settlementTradeDto.setStatusLabel(SettlementEnum.getStatusDesc(settlementTradeDto.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.TRADE.getStatus(), payType);

            } else {
                settlementVoList = kwpSettlementWalletService.queryList(id, SettlementOrderTypeEnum.TRADE.getStatus(), payType);
            }
        }
        settlementVoList.forEach(SpliceUrl::appendPrefix);
        return new SettlementDetailDto<>(settlementTradeDto, settlementVoList);
    }

    /**
     * @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 settlementTradeMapper.sumMoneyType(entId, cur, pre, unitType);
    }

    /**
     * 管理端导出数据
     *
     * @param settlementReq
     * @param idList
     * @return
     */
    public List<SettlementTradeVo> exportList(SettlementTradeReq settlementReq, List<Long> idList) {
        List<SettlementTradeDto> settlementTradeDtos = settlementTradeMapper.exportList(settlementReq, idList);
        if (CollectionUtils.isEmpty(settlementTradeDtos)) {
            return null;
        }
        changeDict(settlementTradeDtos);
        List<SettlementTradeVo> res = new ArrayList<>();
        SettlementTradeVo settlementTradeVo;
        for (SettlementTradeDto settlementTradeDto : settlementTradeDtos) {
            settlementTradeVo = new SettlementTradeVo();
            BeanUtils.copyProperties(settlementTradeDto, settlementTradeVo);
            UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(settlementTradeDto.getUpdateBy());
            if (Objects.nonNull(userCacheResDto)) {
                settlementTradeVo.setUpdateByLabel(userCacheResDto.getName());
            }
            res.add(settlementTradeVo);
        }
        return res;
    }
}
