package com.hzs.report.member.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.enums.ETradeType;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.report.member.mapper.MemberReportMapper;
import com.hzs.report.member.param.ProductDetailQueryParam;
import com.hzs.report.member.service.MemberReportService;
import com.hzs.report.member.vo.*;
import com.hzs.report.report.service.ICuMemberSettlePeriodService;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAccountServiceApi;
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.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MemberReportServiceImpl implements MemberReportService {

    @Autowired
    private MemberReportMapper memberReportMapper;
    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    @DubboReference
    IAccountServiceApi iAccountServiceApi;
    @DubboReference
    ICurrencyServiceApi iCurrencyServiceApi;

    @Override
    public List<DirectPushNewVo> directPushNewList(Long pkMember, String memberName, Integer pkAwards, Integer pkTeamCode, Integer pkCountry, Date startPayTime, Date endPayTime, Integer pkVertex) {
        return memberReportMapper.directPushNewList(pkMember, memberName, pkAwards, pkTeamCode, pkCountry, startPayTime, endPayTime, pkVertex);
    }

    @Override
    public List<DirectPushNewVo> directPushNewAchieList(Long pkMember, Date startPayTime, Date endPayTime, List<Integer> orderType, Integer pkCountry) {
        return memberReportMapper.directPushNewAchieList(pkMember, startPayTime, endPayTime, orderType, pkCountry);
    }

    @Override
    public List<DirectPushNewVo> directPushNewAchieUpList(DirectPushNewVo dpo, Long pkMember, Integer orderType) {
        return memberReportMapper.directPushNewAchieUpList(dpo, pkMember, orderType);
    }

    @Override
    public List<MemberConsumptionVo> memberConsumptionList(String memberCode, String memberName, Date startPayTime, Date endPayTime, Integer pkWares) {
        return memberReportMapper.memberConsumptionList(memberCode, memberName, startPayTime, endPayTime, pkWares);
    }

    @Override
    public List<MemberResettleAchieveVo> memberResettleAchieve(Long pkMember, String memberName, Date startPayTime, Date endPayTime, Integer pkVertex, Integer pkTeamCode,
                                                               Integer pkCountry, Integer pkAwards, List<Integer> orderTypeList) {
        return memberReportMapper.memberResettleAchieve(pkMember, memberName, startPayTime, endPayTime, pkVertex, pkTeamCode, pkCountry, pkAwards, orderTypeList);
    }

    @Override
    public List<MemberResettleAchieveVo> selectBrollyNewABAchieve(Long pkMember, String memberName, Date startPayTime, Date endPayTime, Integer pkVertex,
                                                                  Integer pkTeamCode, Integer pkCountry, Integer pkAwards, String achieveTableName, int period) {
        return memberReportMapper.selectBrollyNewABAchieve(pkMember, memberName, startPayTime, endPayTime,
                pkVertex, pkTeamCode, pkCountry, pkAwards, achieveTableName, period);
    }

    @Override
    public List<OrderCurrencyVo> getOrderCurrencyList(String memberCode, String memberName, String orderCode, Integer orderType) {
        return memberReportMapper.getOrderCurrencyList(memberCode, memberName, orderCode, orderType);
    }

    @Override
    public List<MemberTradeVo> getBySourceCodeMemberTradeList(List<String> orderCodeList) {
        return memberReportMapper.getBySourceCodeMemberTradeList(orderCodeList);
    }

    @Override
    public List<OrderDistribution> getByProvinceOrderDistribution(Date startTime, Date endTime, Integer pkCountry) {
        return memberReportMapper.getByProvinceOrderDistribution(startTime, endTime, pkCountry);
    }

    @Override
    public List<OrderDistribution> getByCityOrderDistribution(Date startTime, Date endTime, Integer pkCountry) {
        return memberReportMapper.getByCityOrderDistribution(startTime, endTime, pkCountry);
    }

    @Override
    public List<OrderDistribution> getByDistrictOrderDistribution(Date startTime, Date endTime, Integer pkCountry) {
        return memberReportMapper.getByDistrictOrderDistribution(startTime, endTime, pkCountry);
    }

    @Override
    public List<ProductOrderInfoVo> getProductOrderInfo(String productName, Integer pkClassify, Date startTime, Date endTime, Integer pkCountry, List<Integer> orderTypeList) {
        return memberReportMapper.getProductOrderInfo(productName, pkClassify, startTime, endTime, pkCountry, orderTypeList);
    }

    @Override
    public List<ReportSummaryVo> reportSummaryList(ReportSummaryVo reportSummaryVo) {
        return memberReportMapper.reportSummaryList(reportSummaryVo);
    }

    @Override
    public List<ProductShippingDetailsInfoVo> productShippingDetailsList(Integer pkProduct, String productName, Integer pkClassify, Integer pkAwards, List<Integer> orderTypeList, Date startTime, Date endTime, Integer pkCountry) {
        return memberReportMapper.productShippingDetailsList(pkProduct, productName, pkClassify, pkAwards, orderTypeList, startTime, endTime, pkCountry);
    }

    @Override
    public List<ProductDetailQueryVo> productDetailQueryList(ProductDetailQueryParam productDetailQueryParam) {
        return memberReportMapper.productDetailQueryList(productDetailQueryParam);
    }

    @Override
    public List<SmallAreaNewAddAchieveVO> selectSmallAreaNewAdd(SmallAreaNewAddAchieveVO addAchieveVO) {
        List<SmallAreaNewAddAchieveVO> areaNewAddAchieveVOList = null;
        //小区新增业绩
        //先计算开始时间减一天期数的业绩，算出大小区，再查询大小区的业绩（历史的）
        //查询时间段内的新增：查询会员表中新增会员的业绩左右区都大于参数的业绩，再区分大小区业绩
        String startDate = addAchieveVO.getStartDate();
        //开始时间的前一天
        LocalDate beforeLocalDate = DateUtils.getStringToLocalDate(startDate).minus(1, ChronoUnit.DAYS);
        //获取期数
        String date = beforeLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //开始时间减一天的期数
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(date).getPkId();
        addAchieveVO.setBeforePeriod(period);
        //查询大小区业绩表
        //String settleTable = TableNameConstants.CU_MEMBER_SETTLE + period;
        addAchieveVO.setSettleTable(getMonthTableName(beforeLocalDate));
        addAchieveVO.setMonthAchieveVOList(getAchieveMonthTable(startDate, addAchieveVO.getEndDate()));
        if (addAchieveVO.getAchieve().compareTo(MagicNumberConstants.big10000) > -1) {
            //查询开始时间前一天大小区的新增业绩
            areaNewAddAchieveVOList = memberReportMapper.selectSmallAreaNewAdd(addAchieveVO);
            //查询时间段时新增会员的大小区新增业绩
            List<SmallAreaNewAddAchieveVO> newMemberList = memberReportMapper.selectSmallAreaNewAddNemMember(addAchieveVO);
            if (CollUtil.isNotEmpty(newMemberList)) {
                areaNewAddAchieveVOList.addAll(newMemberList);
            }
        } else {
            areaNewAddAchieveVOList = memberReportMapper.selectSmallAreaNewAddPage(addAchieveVO);
        }
        return areaNewAddAchieveVOList;
    }

    /**
     * 根据时间获取业绩表名
     *
     * @param localDate 时间
     * @return String
     */
    private String getMonthTableName(LocalDate localDate) {
        return TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    }

    /**
     * 根据开始时间、结束时间获取业绩表信息
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return List<MonthAchieveVO>
     */
    private List<MonthAchieveVO> getAchieveMonthTable(String startDate, String endDate) {
        MonthAchieveVO monthAchieveVO;
        List<MonthAchieveVO> monthAchieveVOList = new ArrayList<>();
        LocalDate startLocalDate = DateUtils.getStringToLocalDate(startDate);
        LocalDate endLocalDate = DateUtils.getStringToLocalDate(endDate);
        Period between = Period.between(startLocalDate, endLocalDate);
        //相差的天数
        int months = between.getMonths();
        //相差两个月及以上
        if (months >= 2) {
            //初月信息
            int startPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(startDate).getPkId();
            MonthAchieveVO startMonthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(startLocalDate))
                    .startPeriod(startPeriod)
                    .build();
            monthAchieveVOList.add(startMonthAchieveVO);
            //中间月信息
            for (int i = 1; i < months; i++) {
                monthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(startLocalDate.plusMonths(i))).build();
                monthAchieveVOList.add(monthAchieveVO);
            }
            //末月信息
            int endPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(endDate).getPkId();
            MonthAchieveVO endMonthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(endLocalDate))
                    .endPeriod(endPeriod)
                    .build();
            monthAchieveVOList.add(endMonthAchieveVO);
            //同一个月
        } else if (months == 0) {
            int startPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(startDate).getPkId();
            int endPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(endDate).getPkId();
            monthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(startLocalDate))
                    .startPeriod(startPeriod).endPeriod(endPeriod).build();
            monthAchieveVOList.add(monthAchieveVO);
        } else {
            //初月信息
            int startPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(startDate).getPkId();
            MonthAchieveVO startMonthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(startLocalDate))
                    .startPeriod(startPeriod)
                    .build();
            monthAchieveVOList.add(startMonthAchieveVO);
            //末月信息
            int endPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(endDate).getPkId();
            MonthAchieveVO endMonthAchieveVO = MonthAchieveVO.builder().achieveTable(getMonthTableName(endLocalDate))
                    .endPeriod(endPeriod)
                    .build();
            monthAchieveVOList.add(endMonthAchieveVO);
        }
        return monthAchieveVOList;
    }

    @Override
    public List<CuMemberWalletVO> selectMemberUnderWalletList(CuMemberWalletVO walletVO) {
        List<CuMemberWalletVO> cuMemberWalletVOList = memberReportMapper.selectMemberUnderWalletList(walletVO);
        if (CollUtil.isNotEmpty(cuMemberWalletVOList)) {
            Integer pkCountry = walletVO.getPkCountry();
            //查询币种值
            List<BdAccount> allAccounts = iAccountServiceApi.queryAccountByType(null, pkCountry).getData();
            Map<Integer, BdAccount> map = allAccounts.stream().collect(Collectors.toMap(BdAccount::getPkId, o -> o));
            Map<String, String> transactionMap = iTransactionCommonService.exportEnumTransaction(ETradeType.values());
            //根据国家查询汇率
            CurrencyDTO currency = iCurrencyServiceApi.getCurrency(pkCountry).getData();
            //汇率
            BigDecimal exchangeRate = currency.getInExchangeRate();
            for (CuMemberWalletVO cuMemberWalletVO : cuMemberWalletVOList) {
                //交易金额
                BigDecimal settleTradeAmount = cuMemberWalletVO.getTradeAmount().divide(exchangeRate, 4, RoundingMode.HALF_UP);
                //交易余额
                BigDecimal settleTradeBalance = cuMemberWalletVO.getTradeBalance().divide(exchangeRate, 4, RoundingMode.HALF_UP);
                cuMemberWalletVO.setSettleTradeAmount(settleTradeAmount);
                cuMemberWalletVO.setSettleTradeBalance(settleTradeBalance);

                //转化备注
                String remarks = cuMemberWalletVO.getRemarks();
                if (StringUtils.isNotEmpty(remarks) && remarks.startsWith(EnumsPrefixConstants.TRADE_TYPE)) {
                    cuMemberWalletVO.setRemarks(transactionMap.get(remarks));
                }

                Integer pkAccount = cuMemberWalletVO.getPkAccount();
                if (null != pkAccount) {
                    cuMemberWalletVO.setPkAccount(map.get(pkAccount).getPkTransactionKey());
                }
            }
        }
        return cuMemberWalletVOList;
    }

    /**
     * 查询商品统计信息
     *
     * @param
     * @return
     */
    @Override
    public List<ProductSaleStatVo> productSaleStatList(String skuCode, String productName, Integer orderType, Date startTime, Date endTime, Integer pkCountry) {
        return memberReportMapper.productSaleStatList(skuCode, productName, orderType, startTime, endTime, pkCountry);
    }

    /**
     * 统计产品所有汇总
     *
     * @param productName
     * @param pkClassify
     * @param startTime
     * @param endTime
     * @param pkCountry
     * @param orderTypeList
     * @return
     */
    @Override
    public Integer sumQuantity(String productName, Integer pkClassify, Date startTime, Date endTime, Integer pkCountry, List<Integer> orderTypeList) {
        return memberReportMapper.sumQuantity(productName, pkClassify, startTime, endTime, pkCountry, orderTypeList);
    }


}
