package com.hzs.retail.member.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.hzs.common.core.enums.EYesNo;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.retail.member.param.MarketDynamicsQueryDateParam;
import com.hzs.retail.member.vo.BigAndSmallRangeVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsResultVO;
import com.hzs.retail.member.vo.MarketDynamicsDetailVO;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户统计数据工具
 * 主要用户统计用户的业绩/明细等
 * 主要处理的类为
 *
 * @link com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO
 */
public class DataStatisticsUtil {

    private static final Long SELF_VIRTUAL_ID = -1000L;
    private static final String SELF_VIRTUAL_NAME = "个人消费虚拟分支";

    public static CuMemberRetailDataStatisticsResultVO getCalcMap(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, CuMember cuMember) {
        Long pkId = cuMember.getPkId();
        // 非激活直接返0
        // 激活判断上一天的ENABLE_STATUS 0为正常 1为当天激活 不计算日结数据
        if (EYesNo.NO.getIntValue() == cuMember.getIsActivate()) {
            return CuMemberRetailDataStatisticsResultVO.builder()
                    .totalPv(BigDecimal.ZERO)
                    .bigRangeTotalPv(BigDecimal.ZERO)
                    .smallRangeTotalPv(BigDecimal.ZERO)
                    .build();
        }
        calcDetailVOTotalField(detailVOList, pkId);
        addVirtualBranch(detailVOList, pkId);
        CuMemberRetailDataStatisticsDetailVO total = getDetailVOByPKID(detailVOList, pkId);
        if (EYesNo.NO.getIntValue() == cuMember.getIsActivate()) {
            // 昨日非激活 排除昨日日结表数据
            excludeDailySettlementData(detailVOList);
        }
        CuMemberRetailDataStatisticsDetailVO bigRangePv = getBigRangePVDetailVO(detailVOList, pkId);
        BigDecimal smallRangeTotalPv = total.getTotalPv().subtract(bigRangePv.getTotalPv());
        if (smallRangeTotalPv.compareTo(BigDecimal.ZERO) < 0) {
            smallRangeTotalPv = BigDecimal.ZERO;
        }
        return CuMemberRetailDataStatisticsResultVO.builder()
                .totalPv(formatPV(total.getTotalPv()))
                .bigRangeTotalPv(formatPV(bigRangePv.getTotalPv()))
                .smallRangeTotalPv(formatPV(smallRangeTotalPv))
                .build();
    }

    /**
     * 计算集合内数据总数
     *
     * @param detailVOList
     */
    public static void calcDetailVOTotalField(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId) {
        detailVOList.forEach(detailVO -> {
            detailVO.setTotalPv(
                    detailVO.getConsumePv()
                            .add(detailVO.getTeamConsumePv())
                            .add(detailVO.getSNewConsumePv())
                            .add(detailVO.getSTeamNewPv())
            );
        });
    }

    /**
     * 排除昨日日结数据
     *
     * @param detailVOList
     */
    public static void excludeDailySettlementData(List<CuMemberRetailDataStatisticsDetailVO> detailVOList) {
        detailVOList.forEach(detailVO -> {
            detailVO.setTotalPv(
                    detailVO.getTotalPv().subtract(detailVO.getTeamConsumePv())
            );
        });
    }

    /**
     * 增加虚拟分支 主要为
     * 1.自己的消费总数
     * 2.注水的大小区
     *
     * @param detailVOList
     */
    public static void addVirtualBranch(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId) {
        CuMemberRetailDataStatisticsDetailVO detailVO = getDetailVOByPKID(detailVOList, pkId);
        if (ObjectUtil.isNotEmpty(detailVO)) {
            CuMemberRetailDataStatisticsDetailVO selfVirtualDetailVO = getCuMemberRetailDataStatisticsDetailVO(detailVO);
            detailVOList.add(selfVirtualDetailVO);
        }
    }

    private static CuMemberRetailDataStatisticsDetailVO getCuMemberRetailDataStatisticsDetailVO(CuMemberRetailDataStatisticsDetailVO detailVO) {
        return CuMemberRetailDataStatisticsDetailVO.builder()
                .pkId(SELF_VIRTUAL_ID)
                .memberCode(SELF_VIRTUAL_NAME)
                .totalPv(
                        detailVO.getConsumePv()
                                .add(detailVO.getSNewConsumePv())
                )
                .build();
    }

    /**
     * 根据ID获取对应数据
     *
     * @param detailVOList
     * @return
     */
    public static CuMemberRetailDataStatisticsDetailVO getDetailVOByPKID(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId) {
        return detailVOList.stream().filter(o -> o.getPkId().equals(pkId)).findFirst().orElse(null);
    }

    /**
     * 组装市场动态列表数据
     *
     * @param detailVOList
     */
    public static PageResult<MarketDynamicsDetailVO> getMarketDynamicsAssemblyData(List<MarketDynamicsDetailVO> detailVOList, MarketDynamicsQueryDateParam param) {
        if (StrUtil.isNotEmpty(param.getKeyWords())) {
            detailVOList = detailVOList.stream().filter(o -> o.getMemberCode().contains(param.getKeyWords()) || o.getMemberName().contains(param.getKeyWords())).collect(Collectors.toList());
        }
        MarketDynamicsDetailVO bigRange;
        if (param.getQueryType().equals(1)) {
            bigRange = detailVOList.stream()
                    .max(Comparator.comparing(MarketDynamicsDetailVO::getTotalBoxNum, BigDecimal::compareTo))
                    .orElse(null);
        } else {
            bigRange = detailVOList.stream()
                    .max(Comparator.comparing(MarketDynamicsDetailVO::getTodayPv))
                    .orElse(null);
        }
        MarketDynamicsDetailVO finalBigRange = bigRange;
        detailVOList = detailVOList.stream().filter(o -> !o.getPkId().equals(finalBigRange.getPkId())).collect(Collectors.toList());
        PageResult<MarketDynamicsDetailVO> result = MemoryPageUtils.paginate(detailVOList, param.getPageNum(), param.getPageSize());
        result.setBigRange(bigRange);
        return result;
    }

    private static CuMemberRetailDataStatisticsDetailVO getBigRangePVDetailVO(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId) {
        return detailVOList.stream()
                .filter(vo -> !vo.getPkId().equals(pkId))
                .max(Comparator.comparing(CuMemberRetailDataStatisticsDetailVO::getTotalPv))
                .orElse(null);
    }

    public static BigDecimal formatPV(BigDecimal pv) {
        return pv.divide(
                new BigDecimal("10000"),
                4,
                RoundingMode.FLOOR
        );
    }

    public static void setQueryDateParam(MarketDynamicsQueryDateParam param) {
        LocalDate.now(ZoneId.of("Asia/Shanghai"));
        LocalDate currentDate = LocalDate.now();
        LocalDate yesterdayDate = currentDate.minusDays(1);
        LocalDate previousMonthDate = currentDate.minusMonths(1);
        LocalDate lastDayOfPreviousMonth = previousMonthDate.with(TemporalAdjusters.lastDayOfMonth());
        param.setNowDate(currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        param.setYesterdayDate(yesterdayDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        param.setLastMonthDate(lastDayOfPreviousMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    }

    public static BigAndSmallRangeVO getBigAndSmallRangeVO(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, CuMember cuMember) {
        Long pkId = cuMember.getPkId();
        BigAndSmallRangeVO bigAndSmallRangeVO = new BigAndSmallRangeVO();
        // 非激活直接返0
        // 激活判断上一天的ENABLE_STATUS 0为正常 1为当天激活 不计算日结数据
        if (EYesNo.NO.getIntValue() == cuMember.getIsActivate()) {
            return null;
        }
        calcDetailVOTotalField(detailVOList, pkId);
        addVirtualBranch(detailVOList, pkId);
        if (EYesNo.NO.getIntValue() == cuMember.getIsActivate()) {
            // 昨日非激活 排除昨日日结表数据
            excludeDailySettlementData(detailVOList);
        }
        CuMemberRetailDataStatisticsDetailVO big = getBigRangePVDetailVO(detailVOList, pkId);
        bigAndSmallRangeVO.setBigRangeId(big.getPkId());
        List<Long> smallIdList = detailVOList.stream()
                .map(CuMemberRetailDataStatisticsDetailVO::getPkId).filter(id -> !id.equals(big.getPkId())).collect(Collectors.toList());
        bigAndSmallRangeVO.setSmallRangeId(smallIdList);
        return bigAndSmallRangeVO;
    }
}
