package com.hzs.bonus.achieve.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.bonus.achieve.service.ICuMemberAchieveService;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.achieve.service.ICuMemberTreeService;
import com.hzs.bonus.bonus.param.BonusParam;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.enums.EOrderType;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.member.achieve.CuMemberAchieve;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.ext.CuMemberSettleCountryExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.bonus.achieve.mapper.CuMemberAchieveMapper;
import com.hzs.bonus.achieve.param.MemberAchieveParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 * 会员业绩记录 服务实现类
 * </p>
 *
 * @author hzs
 * @since 2022-10-26
 */
@Slf4j
@Service
public class CuMemberAchieveServiceImpl extends ServiceImpl<CuMemberAchieveMapper, CuMemberAchieve> implements ICuMemberAchieveService {

    private ICuMemberTreeService cuMemberTreeService;

    private CuMemberBonusSettle cuMemberBonusSettle;

    private ICuMemberSettlePeriodService cuMemberSettlePeriodService;


    @Autowired
    public void setCuMemberSettlePeriodService(ICuMemberSettlePeriodService cuMemberSettlePeriodService) {
        this.cuMemberSettlePeriodService = cuMemberSettlePeriodService;
    }

    @Autowired
    public void setCuMemberBonusSettle(CuMemberBonusSettle cuMemberBonusSettle) {
        this.cuMemberBonusSettle = cuMemberBonusSettle;
    }

    @Autowired
    public void setCuMemberTreeService(ICuMemberTreeService cuMemberTreeService) {
        this.cuMemberTreeService = cuMemberTreeService;
    }

    @Autowired
    ITransactionCommonService iTransactionCommonService;

    @Override
    public String createCuMemberAchieve(String date) {
        // 创建业绩月表记录表
        String tableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
        Integer num = cuMemberTreeService.queryExistOracleTable(tableName);
        if (num == null || num <= 0) {
            baseMapper.createCuMemberAchieveTable(tableName);
            cuMemberTreeService.createCuMemberTableUniqueIndex(tableName);
            cuMemberTreeService.createCuMemberTableSequence(tableName, TableNameConstants.CU_MEMBER_ACHIEVE_SEQ);
        }
        return tableName;
    }

    @Override
    public void createCuMemberMonthTable(String tableName) {
        baseMapper.createCuMemberMonthTable(tableName);
    }

    @Override
    public void mergeCuMemberMonth(Integer day, String date) {
        String tableName = TableNameConstants.CU_MEMBER_MONTH + DateUtils.getMonth(date);
        CuMemberSettlePeriod cuMemberSettlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(date);
        // 每月6号删除上月数据,重新生成
//        if (day == 6) {
        Integer number = cuMemberTreeService.queryExistOracleTable(tableName);
        if (number != null && number > 0) {
            cuMemberTreeService.truncateCuMemberTreeTable(tableName);
        }
//        }
        baseMapper.mergeCuMemberMonth(DateUtils.getMonth(date), cuMemberSettlePeriod.getPkId());
    }

    @Override
    public void insertCuMemberAchieveBySettleDate(String targetTableName, String sourceTableName, Integer period) {
        baseMapper.insertCuMemberAchieveBySettleDate(targetTableName, sourceTableName, period);
    }

    @Override
    public void mergeCuMemberAchieveBySettleDate(String targetTableName, String sourceTableName, Integer period) {
        baseMapper.mergeCuMemberAchieveBySettleDate(targetTableName, sourceTableName, period);
    }

    /*
     * @description:更新为初始化的数据，防止当天新增的数据
     * @author: sui q
     * @date: 2023/8/11 14:56
     * @param: null null
     **/
    @Override
    public void updateCuMemberSettleInitAchieve(String targetTable, String currentTableNameDetail, String currentTableNameCountry) {
        baseMapper.updateCuMemberSettleInitAchieve(targetTable);
        baseMapper.updateCuMemberSettleDetailInitAchieve(currentTableNameDetail);
        baseMapper.updateCuMemberCountryDetailInitAchieve(currentTableNameCountry);
    }

    @Override
    public void updateCuMemberSettleAchieveByBeforeDay(String sourceTable, String targetTable, String yesterdayTableNameDetail, String currentTableNameDetail, Integer endPeriod,
                                                       String sourceCountryTable, String targetCountryTable) {
        baseMapper.updateCuMemberSettleAchieveByBeforeDay(sourceTable, targetTable, endPeriod);
        baseMapper.updateCuMemberSettleAchieveDetailByBeforeDay(yesterdayTableNameDetail, currentTableNameDetail, endPeriod);
        baseMapper.updateCuMemberSettleCountryDetailByBeforeDay(sourceCountryTable, targetCountryTable);
    }

    @Override
    public void mergeBackCuMemberReSaleDate(String targetTable, Integer period) {
        baseMapper.mergeBackCuMemberReSaleDate(targetTable, period);
    }

    @Override
    public void updateCuMemberSettleAchieveBySpecialBus(String targetTable, Integer period, Long pkId) {
        baseMapper.updateCuMemberSettleAchieveBySpecialBus(targetTable, period, pkId);
    }

    @Override
    public Boolean updateCuMemberAchieveEveryDay(Map<Long, MemberAchieveParam> memberAchieveParamMap, String tablaName, String settleTableNameDetail) {
        if (memberAchieveParamMap.size() > 0) {
            List<MemberAchieveParam> memberAchieveParamList = new ArrayList<>();
            memberAchieveParamMap.forEach((key, memberAchieveParam) ->
                    memberAchieveParamList.add(memberAchieveParam));
            List<List<?>> listList = cuMemberBonusSettle.handleCutList(memberAchieveParamList, MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM);
            listList.forEach(list -> {
                // 更新安置业绩
                baseMapper.updateCuMemberBackAchieveEveryDay(list, settleTableNameDetail, tablaName);
                // 更新血缘业绩
                baseMapper.updateCuMemberBloodAchieveEveryDate(list, tablaName);
            });
        }
        return true;
    }

    @Override
    public void updateCuMemberBackOldAchieveEveryDay(Map<Long, MemberAchieveParam> memberAchieveParamMap, String tablaName, String settleTableNameDetail) {
        if (memberAchieveParamMap.size() > 0) {
            List<MemberAchieveParam> memberAchieveParamList = new ArrayList<>();
            memberAchieveParamMap.forEach((key, memberAchieveParam) ->
                    memberAchieveParamList.add(memberAchieveParam));
            List<List<?>> listList = cuMemberBonusSettle.handleCutList(memberAchieveParamList, MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM);
            listList.forEach(list -> {
                baseMapper.updateCuMemberBackOldAchieveEveryDay(list, tablaName, settleTableNameDetail);
            });
        }
    }

    @Override
    public Boolean chargeBackSaOrder(SaOrder saOrder) {
        // 根据支付时间查询期间
        // 查询期间的cu_member_tree 查询网体，根据网体更新业绩，更新7天前到昨天网体业绩
        MemberAchieveParam cuMemberAchieve = MemberAchieveParam.builder()
                .pkRate(saOrder.getPkRate())
                .pkMember(saOrder.getPkMember())
                .newAmount(BigDecimal.ZERO)
                .newPv(BigDecimal.ZERO)
                .build();
        if (Objects.equals(EOrderType.REGISTER_ORDER.getValue(), saOrder.getOrderType()) ||
                Objects.equals(EOrderType.UPGRADE_ORDER.getValue(), saOrder.getOrderType())) {
            cuMemberAchieve.setNewAmount(saOrder.getOrderAmount());
            cuMemberAchieve.setNewPv(saOrder.getOrderAchieve());
        }
        String payTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, saOrder.getPayTime());
        int period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(payTime).getPkId();
        String sourceTable = TableNameConstants.CU_MEMBER_SETTLE + period;
        for (int i = 7; i > 0; i--) {
            String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(i, ChronoUnit.DAYS));
            int settlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
            String targetTable = TableNameConstants.CU_MEMBER_SETTLE_D + settlePeriod;
            baseMapper.chargeBackSaOrder(targetTable, sourceTable, period, cuMemberAchieve);
        }
        return Boolean.TRUE;
    }

    @Override
    public List<CuMemberSettleCountryExt> queryCuMemberSettleCountry(BonusParam bonusParam) {
        if (bonusParam.getSettleDate() == null) {
            bonusParam.setSettleDate(DateUtils.beforeDate(1, ChronoUnit.DAYS));
        }else{
            if(DateUtils.compareDateAfter(bonusParam.getSettleDate(), DateUtils.beforeDate(1, ChronoUnit.DAYS))){
                bonusParam.setSettleDate(DateUtils.beforeDate(1, ChronoUnit.DAYS));
            }
        }
        String settleDate = DateUtils.parseDateToFormat(DateUtils.YYYY_MM_DD, bonusParam.getSettleDate());
        Integer period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
        String currentCountryTableNameDetail = TableNameConstants.CU_MEMBER_SETTLE_C + period;
        List<CuMemberSettleCountryExt> cuMemberSettleCountryExtList = baseMapper.queryCuMemberSettleCountry(currentCountryTableNameDetail, bonusParam);
        List<CuMemberSettleCountryExt> returnCountry = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(cuMemberSettleCountryExtList)) {
            Map<String, List<CuMemberSettleCountryExt>> settleCountryMap = new HashMap<>();
            for (CuMemberSettleCountryExt cuMemberSettleCountryExt : cuMemberSettleCountryExtList) {
                String key = cuMemberSettleCountryExt.getPlaceDept() + "_" + cuMemberSettleCountryExt.getPkCountry();
                if (settleCountryMap.containsKey(key)) {
                    List<CuMemberSettleCountryExt> cuMemberSettleCountryExtList1 = settleCountryMap.get(key);
                    cuMemberSettleCountryExtList1.add(cuMemberSettleCountryExt);
                } else {
                    List<CuMemberSettleCountryExt> cuMemberSettleCountryExtList1 = new ArrayList<>();
                    cuMemberSettleCountryExtList1.add(cuMemberSettleCountryExt);
                    settleCountryMap.put(key, cuMemberSettleCountryExtList1);
                }
            }
            for (String key : settleCountryMap.keySet()) {
                List<CuMemberSettleCountryExt> cuMemberSettleCountryExtList1 = settleCountryMap.get(key);
                CuMemberSettleCountryExt cuMemberSettleCountryExt = BeanUtil.copyProperties(cuMemberSettleCountryExtList1.get(0), CuMemberSettleCountryExt.class);
                cuMemberSettleCountryExt.setPkCountry(null);
                cuMemberSettleCountryExt.setCountryName(null);
                if(cuMemberSettleCountryExtList1.size() > 1) {
                    for (int i = 1; i < cuMemberSettleCountryExtList1.size(); i++) {
                        CuMemberSettleCountryExt newCuMemberSettleCountryExt = cuMemberSettleCountryExtList1.get(i);
                        cuMemberSettleCountryExt.setSumPv(ComputeUtil.computeAdd(cuMemberSettleCountryExt.getSumPv(), newCuMemberSettleCountryExt.getSumPv()));
                        cuMemberSettleCountryExt.setNewPv(ComputeUtil.computeAdd(cuMemberSettleCountryExt.getNewPv(), newCuMemberSettleCountryExt.getNewPv()));
                    }
                }
                cuMemberSettleCountryExt.setCuMemberSettleCountryExtList(cuMemberSettleCountryExtList1);
                returnCountry.add(cuMemberSettleCountryExt);
            }
        }
        return returnCountry;
    }

    /**
     * 获取业绩表名
     *
     * @param localDate 日期
     * @return String
     */
    private String getAchieveTable(LocalDate localDate) {
        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(date);
    }


}
