package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.SalesRewardWorthStatisticsMapper;
import com.crm.manager.dao.repository.*;
import com.crm.manager.dto.export.TradeSalesRewardExportDto;
import com.crm.manager.service.SelesRewardWorthStatisticsService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.BaseReportResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.ib.trade.TradeSalesRewardDto;
import com.crm.rely.backend.core.dto.ib.trade.TradeSalesRewardSumDto;
import com.crm.rely.backend.core.dto.sales.SalesRewardDto;
import com.crm.rely.backend.core.entity.base.BaseIbReportListEntity;
import com.crm.rely.backend.core.entity.custom.info.InfoEntity;
import com.crm.rely.backend.core.pojo.table.*;
import com.crm.rely.backend.core.pojo.view.TradeSalesRewardView;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.FormatPage;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SelesRewardWorthStatisticsServiceImpl implements SelesRewardWorthStatisticsService {

    @Autowired
    private SalesRewardWorthStatisticsMapper worthStatisticsMapper;
    @Autowired
    private SalesRewardWorthStatisticsRepository salesRewardWorthStatisticsRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void salesDepositStatisticsTask() throws Exception {
        Date startDate = DateUtil.addDate(new Date(), -1);

        //查询入金总额
        List<SalesRewardDto> salesDeponsitList = worthStatisticsMapper.getSalesDepositSum(startDate);

        //查询出金总额
        List<SalesRewardDto> salesWithdrawList = worthStatisticsMapper.getSalesWithdrawSum(startDate);
        Map<Long, SalesRewardDto> withdrawMap = salesWithdrawList.stream().collect(Collectors.toMap(SalesRewardDto::getSalesId, SalesRewardDto -> SalesRewardDto));

        //查询佣金提取总额
        List<SalesRewardDto> salesAgentWithdrawList = worthStatisticsMapper.getSalesAgentWithdrawSum(startDate);
        Map<Long, SalesRewardDto> agentWithdrawMap = salesAgentWithdrawList.stream().collect(Collectors.toMap(SalesRewardDto::getSalesId, SalesRewardDto -> SalesRewardDto));

        //查询注册人数
        List<SalesRewardDto> addCustomList = worthStatisticsMapper.getSalesAddCustomSum(startDate);
        Map<Long, SalesRewardDto> addCustomMap = addCustomList.stream().collect(Collectors.toMap(SalesRewardDto::getSalesId, SalesRewardDto -> SalesRewardDto));

        //查询真实账户人数
        List<SalesRewardDto> realCustomList = worthStatisticsMapper.getSalesRealCustomSum(startDate);
        Map<Long, SalesRewardDto> realCustomMap = realCustomList.stream().collect(Collectors.toMap(SalesRewardDto::getSalesId, SalesRewardDto -> SalesRewardDto));

        List<SalesRewardWorthStatisticsTable> tableList = new ArrayList<>();
        for (SalesRewardDto salesDeponsitDto : salesDeponsitList) {
            SalesRewardWorthStatisticsTable table = new SalesRewardWorthStatisticsTable();
            table.setSalesId(salesDeponsitDto.getSalesId());
            table.setDepositAmount(salesDeponsitDto.getDepositAmount());
            if(withdrawMap.containsKey(salesDeponsitDto.getSalesId())) {
                table.setWithdrawAmount(withdrawMap.get(salesDeponsitDto.getSalesId()).getWithdrawAmount());
                withdrawMap.remove(salesDeponsitDto.getSalesId());
            }else{
                table.setWithdrawAmount(0f);
            }
            if(agentWithdrawMap.containsKey(salesDeponsitDto.getSalesId())) {
                table.setAgentWithdrawAmount(agentWithdrawMap.get(salesDeponsitDto.getSalesId()).getWithdrawAmount());
                agentWithdrawMap.remove(salesDeponsitDto.getSalesId());
            }
            if(addCustomMap.containsKey(salesDeponsitDto.getSalesId())) {
                table.setAddCustomNum(addCustomMap.get(salesDeponsitDto.getSalesId()).getCustomNum());
                addCustomMap.remove(salesDeponsitDto.getSalesId());
            }
            if(realCustomMap.containsKey(salesDeponsitDto.getSalesId())) {
                table.setRealCustomNum(realCustomMap.get(salesDeponsitDto.getSalesId()).getCustomNum());
                realCustomMap.remove(salesDeponsitDto.getSalesId());
            }

            table.setWorthDepositAmount(new BigDecimal(table.getDepositAmount()).subtract(new BigDecimal(table.getWithdrawAmount())).floatValue());
            table.setStatisticsDate(DateUtil.addDate(new Date(), -1));

            tableList.add(table);
        }

        if(withdrawMap.size() > 0){
            getList(withdrawMap,agentWithdrawMap,addCustomMap,realCustomMap,tableList);
        }

        if(agentWithdrawMap.size() > 0){
            getList(agentWithdrawMap,addCustomMap,realCustomMap,tableList);
        }

        if(addCustomMap.size() > 0){
            getList(addCustomMap,realCustomMap,tableList);
        }

        if(realCustomMap.size() > 0){
            getList(realCustomMap,tableList);
        }

        salesRewardWorthStatisticsRepository.save(tableList);

    }

    private void getList(Map<Long, SalesRewardDto> withdrawMap, Map<Long, SalesRewardDto> agentWithdrawMap, Map<Long, SalesRewardDto> addCustomMap, Map<Long, SalesRewardDto> realCustomMap,List<SalesRewardWorthStatisticsTable> tableList) {
        for (Long salesId : withdrawMap.keySet()) {
            SalesRewardDto reward = withdrawMap.get(salesId);

            SalesRewardWorthStatisticsTable table = new SalesRewardWorthStatisticsTable();
            table.setSalesId(reward.getSalesId());
            table.setDepositAmount(0f);
            table.setWithdrawAmount(reward.getWithdrawAmount());
            if (agentWithdrawMap.containsKey(salesId)) {
                table.setAgentWithdrawAmount(agentWithdrawMap.get(salesId).getWithdrawAmount());
                agentWithdrawMap.remove(salesId);
            }
            if(addCustomMap.containsKey(salesId)) {
                table.setAddCustomNum(addCustomMap.get(salesId).getCustomNum());
                addCustomMap.remove(salesId);
            }
            if(realCustomMap.containsKey(salesId)) {
                table.setRealCustomNum(realCustomMap.get(salesId).getCustomNum());
                realCustomMap.remove(salesId);
            }
            table.setWorthDepositAmount(new BigDecimal(table.getDepositAmount()).subtract(new BigDecimal(table.getWithdrawAmount())).floatValue());
            table.setStatisticsDate(DateUtil.addDate(new Date(), -1));

            tableList.add(table);
        }

    }

    private void getList(Map<Long, SalesRewardDto> agentWithdrawMap, Map<Long, SalesRewardDto> addCustomMap, Map<Long, SalesRewardDto> realCustomMap,List<SalesRewardWorthStatisticsTable> tableList) {
        for (Long salesId : agentWithdrawMap.keySet()) {
            SalesRewardDto reward = agentWithdrawMap.get(salesId);
            SalesRewardWorthStatisticsTable table = new SalesRewardWorthStatisticsTable();
            table.setSalesId(reward.getSalesId());
            table.setAgentWithdrawAmount(reward.getWithdrawAmount());
            if(addCustomMap.containsKey(salesId)) {
                table.setAddCustomNum(addCustomMap.get(salesId).getCustomNum());
                addCustomMap.remove(salesId);
            }
            if(realCustomMap.containsKey(salesId)) {
                table.setRealCustomNum(realCustomMap.get(salesId).getCustomNum());
                realCustomMap.remove(salesId);
            }
            table.setStatisticsDate(DateUtil.addDate(new Date(), -1));

            tableList.add(table);
        }
    }

    private void getList(Map<Long, SalesRewardDto> addCustomMap, Map<Long, SalesRewardDto> realCustomMap,List<SalesRewardWorthStatisticsTable> tableList) {
        for (Long salesId : addCustomMap.keySet()) {
            SalesRewardDto reward = addCustomMap.get(salesId);
            SalesRewardWorthStatisticsTable table = new SalesRewardWorthStatisticsTable();
            table.setSalesId(reward.getSalesId());
            table.setAddCustomNum(reward.getCustomNum());
            if(realCustomMap.containsKey(salesId)) {
                table.setRealCustomNum(realCustomMap.get(salesId).getCustomNum());
                realCustomMap.remove(salesId);
            }
            table.setStatisticsDate(DateUtil.addDate(new Date(), -1));

            tableList.add(table);
        }
    }

    private void getList(Map<Long, SalesRewardDto> realCustomMap,List<SalesRewardWorthStatisticsTable> tableList) {
        for (Long salesId : realCustomMap.keySet()) {
            SalesRewardDto reward = realCustomMap.get(salesId);
            SalesRewardWorthStatisticsTable table = new SalesRewardWorthStatisticsTable();
            table.setSalesId(reward.getSalesId());
            table.setRealCustomNum(reward.getCustomNum());
            table.setStatisticsDate(DateUtil.addDate(new Date(), -1));

            tableList.add(table);
        }
    }

    @Override
    public BaseReportResultDto<List<TradeSalesRewardDto>, TradeSalesRewardSumDto> tradeSalesReward(BaseIbReportListEntity entity, InfoEntity infoEntity) throws Exception{

        Integer count = worthStatisticsMapper.countSearch(entity);
        PageDto pageDto = FormatPage.format(entity.getPage(), count);
        if (count == null || count == 0) {
            return new BaseReportResultDto(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto);
        }

        List<TradeSalesRewardView> views = worthStatisticsMapper.pageSearch(entity);
        List<TradeSalesRewardDto> dtos = convertToDto(views);

        TradeSalesRewardView sumView = worthStatisticsMapper.sumSearch(entity);
        TradeSalesRewardSumDto sumDto = TradeSalesRewardSumDto.getInstance();
        BeanUtils.copyProperties(sumView, sumDto);

        return new BaseReportResultDto<>(dtos, sumDto, pageDto);
    }

    @Override
    public List<TradeSalesRewardExportDto> tradeSalesRewardExport(BaseIbReportListEntity entity, InfoEntity infoEntity) throws Exception {
        entity.setPage(null);
        List<TradeSalesRewardView> views = worthStatisticsMapper.pageSearch(entity);
        List<TradeSalesRewardExportDto> dtos = convertToExportDto(views);
        return dtos;
    }

    private List<TradeSalesRewardDto> convertToDto(List<TradeSalesRewardView> views) throws Exception {
        if (CollectionUtils.isEmpty(views)) return Lists.newArrayList();
        List<TradeSalesRewardDto> dtos = Lists.newArrayList();
        views.forEach(view -> {
            TradeSalesRewardDto dto = TradeSalesRewardDto.getInstance();
            BeanUtils.copyProperties(view, dto);
            dtos.add(dto);
        });

        return dtos;
    }

    private List<TradeSalesRewardExportDto> convertToExportDto(List<TradeSalesRewardView> views) throws Exception {
        if (CollectionUtils.isEmpty(views)) return Lists.newArrayList();
        List<TradeSalesRewardExportDto> dtos = Lists.newArrayList();
        views.forEach(view -> {
            TradeSalesRewardExportDto dto = new TradeSalesRewardExportDto();
            BeanUtils.copyProperties(view, dto);
            dto.setCID(view.getCId());
            dtos.add(dto);
        });

        return dtos;

    }

}
