package com.crm.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.manager.dao.mapper.SalesLeaderMapper;
import com.crm.manager.dao.mapper.SalesPerformanceMapper;
import com.crm.manager.dao.repository.SalesLeaderRepository;
import com.crm.manager.dao.repository.SalesPerformanceRepository;
import com.crm.manager.dao.repository.UserInfoRepository;
import com.crm.manager.dto.export.TradeSalesPerformanceExportDto;
import com.crm.manager.dto.export.TradeSalesPerformanceExportEnDto;
import com.crm.manager.service.SelesPerformanceService;
import com.crm.manager.service.SysConfigService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.EmailSendEnum;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.SystemEmailCodeConstants;
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.TradeSalesPerformanceDto;
import com.crm.rely.backend.core.dto.ib.trade.TradeSalesPerformanceSumDto;
import com.crm.rely.backend.core.dto.sales.SalesPerformanceDto;
import com.crm.rely.backend.core.entity.sales.SalesPerformanceListEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.pojo.table.SalesLeaderTable;
import com.crm.rely.backend.core.pojo.table.SalesPerformanceTable;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.pojo.table.UserInfoTable;
import com.crm.rely.backend.core.pojo.view.SalesLeaderListview;
import com.crm.rely.backend.core.pojo.view.TradeSalesPerformanceView;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.CountryUtil;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.ExportUtil;
import com.crm.rely.backend.util.FormatPage;
import com.google.common.base.Strings;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import lombok.extern.log4j.Log4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Log4j
@Service
public class SelesPerformanceServiceImpl implements SelesPerformanceService {

    @Autowired
    private SalesPerformanceMapper salesPerformanceMapper;
    @Autowired
    private SalesPerformanceRepository salesPerformanceRepository;
    @Autowired
    private SalesLeaderRepository salesLeaderRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private EmailService emailService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private ListeningExecutorService listeningExecutorService;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private SalesLeaderMapper salesLeaderMapper;

    @Autowired
    @Value("${web.export-path}")
    private String exportPath;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void salesPerformanceTask(Date startDate, String salesNo) throws Exception {
        // 删除当天旧数据
        salesPerformanceMapper.deleteSalesPerformanceByDate(startDate, salesNo);

        // 获取销售负责人列表
        List<SalesLeaderTable> leaderTables = Strings.isNullOrEmpty(salesNo)
                ? salesLeaderRepository.findAll()
                : salesLeaderRepository.findBySalesNo(salesNo);

        // 线程安全的结果列表
        List<SalesPerformanceTable> performanceList = Collections.synchronizedList(new ArrayList<>());

        List<ListenableFuture<Integer>> futures = new ArrayList<>();

        for (SalesLeaderTable leaderTable : leaderTables) {
            futures.add(listeningExecutorService.submit(() -> {
                try {
                    // 查询负责人信息
                    UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(leaderTable.getSalesNo());
                    if (userInfo == null) {
                        return 200;
                    }

                    // 查询额外 IB 规则
                    List<SalesLeaderListview> views = salesLeaderMapper.searchExtraIbNo(leaderTable.getSalesNo());
                    List<String> addIbNo = new ArrayList<>();
                    List<String> excludeIbNo = new ArrayList<>();
                    List<String> ibNoList = new ArrayList<>();

                    for (SalesLeaderListview view : views) {
                        if (view.getType() == 1) {
                            if (view.getRoleId() == -1) {
                                ibNoList.add(view.getSalesNo());
                                excludeIbNo.add(view.getSalesNo());
                            } else {
                                addIbNo.add(view.getSalesNo());
                            }
                        } else if (view.getSalesDate() == null || startDate.getTime() >= DateUtil.getMonthStart(DateUtil.addMonth(view.getSalesDate(), 3)).getTime()) {
                            excludeIbNo.add(view.getSalesNo());
                        }
                    }

                    List<SalesPerformanceTable> tableList = new ArrayList<>();

                    // 代理单独统计（批量查询）
                    if (!ibNoList.isEmpty()) {
                        getSalesPerformance(
                                salesPerformanceMapper.getIbSalesDepositSum(startDate, ibNoList),
                                salesPerformanceMapper.getIbSalesWithdrawSum(startDate, ibNoList),
                                salesPerformanceMapper.getIbSalesRealCustomSum(startDate, ibNoList),
                                salesPerformanceMapper.getIbSalesAddCustomSum(startDate, ibNoList),
                                userInfo.getId(),
                                startDate,
                                tableList
                        );
                    }

                    Long leaderId = userInfo.getLeaderId() != null ? userInfo.getLeaderId() : userInfo.getAttachId();

                    // 批量查询四类销售数据（使用 addIbNo / excludeIbNo）
                    getSalesPerformance(
                            salesPerformanceMapper.getSalesDepositSum(startDate, userInfo.getStamp(), leaderId,
                                    addIbNo, excludeIbNo),
                            salesPerformanceMapper.getSalesWithdrawSum(startDate, userInfo.getStamp(), leaderId,
                                    addIbNo, excludeIbNo),
                            salesPerformanceMapper.getSalesRealCustomSum(startDate, userInfo.getStamp(), leaderId,
                                    addIbNo, excludeIbNo),
                            salesPerformanceMapper.getSalesAddCustomSum(startDate, userInfo.getStamp(), leaderId,
                                    addIbNo, excludeIbNo),
                            userInfo.getId(),
                            startDate,
                            tableList
                    );

                    performanceList.addAll(tableList);
                    return 200;
                } catch (Exception e) {
                    log.error("计算销售业绩失败", e);
                    return 400;
                }
            }));
        }

        // 等待所有线程完成
        try {
            ListenableFuture<List<Integer>> all = Futures.allAsList(futures);
            all.get();
        } catch (Exception e) {
            log.error("销售业绩任务执行失败", e);
        }

        // 保存结果
        if (!performanceList.isEmpty()) {
            salesPerformanceRepository.save(performanceList);
        }
    }

    public void getSalesPerformance(List<SalesPerformanceDto> depositList, List<SalesPerformanceDto> withdrawList,
                                    List<SalesPerformanceDto> realCustomList,
                                    List<SalesPerformanceDto> addCustomList, Long leaderId, Date startDate,
                                    List<SalesPerformanceTable> tableList) {
        // 转 map
        Map<Long, SalesPerformanceDto> depositMap = toMap(depositList);
        Map<Long, SalesPerformanceDto> withdrawMap = toMap(withdrawList);
        Map<Long, SalesPerformanceDto> realMap = toMap(realCustomList);
        Map<Long, SalesPerformanceDto> addMap = toMap(addCustomList);

        // 统一汇总所有销售ID
        Set<Long> allSalesIds = new HashSet<>();
        allSalesIds.addAll(depositMap.keySet());
        allSalesIds.addAll(withdrawMap.keySet());
        allSalesIds.addAll(realMap.keySet());
        allSalesIds.addAll(addMap.keySet());

        for (Long salesId : allSalesIds) {
            SalesPerformanceTable table = new SalesPerformanceTable();
            table.setLeaderId(leaderId);
            table.setSalesId(salesId);

            float deposit = depositMap.containsKey(salesId) ? depositMap.get(salesId).getDepositAmount() : 0f;
            float withdraw = withdrawMap.containsKey(salesId) ? withdrawMap.get(salesId).getWithdrawAmount() : 0f;
            int realNum = realMap.containsKey(salesId) ? realMap.get(salesId).getCustomNum() : 0;
            int addNum = addMap.containsKey(salesId) ? addMap.get(salesId).getCustomNum() : 0;

            table.setDepositAmount(deposit);
            table.setWithdrawAmount(withdraw);
            table.setCustomNum(realNum);
            table.setAddCustomNum(addNum);
            table.setWorthDepositAmount(new BigDecimal(deposit).subtract(new BigDecimal(withdraw)).floatValue());
            table.setStatisticsDate(startDate);
            table.setAddTime(new Date());
            tableList.add(table);
        }
    }

    /**
     * 安全的列表转 Map
     */
    private Map<Long, SalesPerformanceDto> toMap(List<SalesPerformanceDto> list) {
        Map<Long, SalesPerformanceDto> map = new HashMap<>();
        if (list != null) {
            for (SalesPerformanceDto dto : list) {
                if (dto.getSalesId() != null && !map.containsKey(dto.getSalesId())) {
                    map.put(dto.getSalesId(), dto);
                }
            }
        }
        return map;
    }

    @Override
    public void salesPerformanceSendEmailTask(Date startDate, Date endDate) throws Exception {
        SalesPerformanceListEntity entity = new SalesPerformanceListEntity();
        entity.setStartDate(startDate);
        entity.setEndDate(endDate);
        entity.setPage(null);
        List<TradeSalesPerformanceView> leaderViews = salesPerformanceMapper.pageSearch(entity);
        if (leaderViews == null || leaderViews.size() == 0) {
            return;
        }

        for (TradeSalesPerformanceView leaderView : leaderViews) {
            entity.setSalesNo(leaderView.getIbNo());
            List<TradeSalesPerformanceView> views = salesPerformanceMapper.salesPerformanceList(entity);

            TradeSalesPerformanceView sumView = salesPerformanceMapper.sumSearch(entity);

            UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
            if (userInfo == null) {
                return;
            }

            SalesLeaderTable leaderTable = salesLeaderRepository.getFirstBySalesNo(entity.getSalesNo());
            if (leaderTable == null) {
                return;
            }

            entity.setSalesNo(leaderView.getIbNo());
            entity.setStamp(userInfo.getStamp());
            entity.setLeaderId(userInfo.getLeaderId());
            List<TradeSalesPerformanceView> salesView = salesPerformanceMapper.findAllSalesByStamp(entity);

            String fileName = genFileName(leaderView.getIbNo());
            if (CountryUtil.isCN(userInfo.getCountry())) {
                List<TradeSalesPerformanceExportDto> dtos = convertToExportDto(views, salesView, sumView,
                        userInfo.getAttachId(), userInfo.getId());
                ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                        TradeSalesPerformanceExportDto.class);
            } else {
                List<TradeSalesPerformanceExportEnDto> dtos = convertToExportEnDto(views, salesView, sumView,
                        userInfo.getAttachId(), userInfo.getId());
                ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                        TradeSalesPerformanceExportEnDto.class);
            }

//            sendSalesPerformanceLeaderEmail(userInfo, exportPath + File.separator + fileName, entity);
            sendSalesPerformanceManagerEmail(userInfo, exportPath + File.separator + fileName, entity);
        }
    }

    @JmsListener(destination = Constants.TRADE_DW_IMPORT_PERFORMANCE)
    @Transactional(rollbackFor = Exception.class)
    public void tradeDwImportPerformance(String content) throws Exception {

        log.info(String.format("TRADE_DW_IMPORT_PERFORMANCE,content:%s", content));
        Set<String> closeDate = JSON.parseObject(content, Set.class);
        if (closeDate == null) {
            log.error("TRADE_DW_IMPORT_PERFORMANCE,closeDate is null");
            return;
        }
        for (String startDate : closeDate) {
            salesPerformanceTask(DateUtil.parseDate(startDate), null);
        }
    }

    @Override
    public BaseReportResultDto<List<TradeSalesPerformanceDto>, TradeSalesPerformanceSumDto> tradePerformance(SalesPerformanceListEntity entity) throws Exception {

        Integer count = salesPerformanceMapper.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<TradeSalesPerformanceView> views = salesPerformanceMapper.pageSearch(entity);
        List<TradeSalesPerformanceDto> dtos = convertToDto(views, null, null);

        TradeSalesPerformanceView sumView = salesPerformanceMapper.sumSearch(entity);
        TradeSalesPerformanceSumDto sumDto = TradeSalesPerformanceSumDto.getInstance();
        BeanUtils.copyProperties(sumView, sumDto);

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

    @Override
    public List<TradeSalesPerformanceDto> tradePerformanceList(SalesPerformanceListEntity entity) throws Exception {
        List<TradeSalesPerformanceView> views = salesPerformanceMapper.salesPerformanceList(entity);

        UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userInfo != null) {
            entity.setStamp(userInfo.getStamp());
        }

        SalesLeaderTable leaderTable = salesLeaderRepository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        entity.setSalesNo(entity.getSalesNo());

        entity.setLeaderId(userInfo.getLeaderId());
        List<TradeSalesPerformanceView> salesView = salesPerformanceMapper.findAllSalesByStamp(entity);

        List<TradeSalesPerformanceDto> dtos = convertToDto(views, salesView, userInfo);
        return dtos;
    }

    @Override
    public List<List<TradeSalesPerformanceExportDto>> tradeSalesPerformanceExport(SalesPerformanceListEntity entity,
                                                                                  List<String> sheetName) throws Exception {
        List<List<TradeSalesPerformanceExportDto>> exportDtos = new ArrayList<>();
        List<TradeSalesPerformanceView> leaderViews = salesPerformanceMapper.pageSearch(entity);

        for (TradeSalesPerformanceView leaderView : leaderViews) {
            entity.setSalesNo(leaderView.getIbNo());
            List<TradeSalesPerformanceView> views = salesPerformanceMapper.salesPerformanceList(entity);

            TradeSalesPerformanceView sumView = salesPerformanceMapper.sumSearch(entity);

            UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
            SalesLeaderTable leaderTable = salesLeaderRepository.getFirstBySalesNo(leaderView.getIbNo());
            List<TradeSalesPerformanceView> salesView = null;
            if (userInfo != null && userInfo.getStamp() != null && leaderTable != null) {
                entity.setStamp(userInfo.getStamp());

                entity.setLeaderId(userInfo.getLeaderId());
                salesView = salesPerformanceMapper.findAllSalesByStamp(entity);
            }

            List<TradeSalesPerformanceExportDto> dtos = convertToExportDto(views, salesView, sumView,
                    userInfo == null ? null : userInfo.getAttachId(), userInfo == null ? null : userInfo.getId());
            exportDtos.add(dtos);

            sheetName.add(leaderView.getIbNo());
        }

        return exportDtos;
    }

    @Override
    public void tradePerformanceSendReport(SalesPerformanceListEntity entity) throws Exception {
        UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userInfo == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        SalesLeaderTable leaderTable = salesLeaderRepository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }


        entity.setPage(null);
        List<TradeSalesPerformanceView> views = salesPerformanceMapper.salesPerformanceList(entity);

        TradeSalesPerformanceView sumView = salesPerformanceMapper.sumSearch(entity);

        entity.setStamp(userInfo.getStamp());
        entity.setSalesNo(entity.getSalesNo());

        entity.setLeaderId(userInfo.getLeaderId());
        List<TradeSalesPerformanceView> salesView = salesPerformanceMapper.findAllSalesByStamp(entity);

        String fileName = genFileName(userInfo.getIbNo());
        if (CountryUtil.isCN(userInfo.getCountry())) {
            List<TradeSalesPerformanceExportDto> dtos = convertToExportDto(views, salesView, sumView,
                    userInfo.getAttachId(), userInfo.getId());
            ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                    TradeSalesPerformanceExportDto.class);
        } else {
            List<TradeSalesPerformanceExportEnDto> dtos = convertToExportEnDto(views, salesView, sumView,
                    userInfo.getAttachId(), userInfo.getId());
            ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                    TradeSalesPerformanceExportEnDto.class);
        }

        sendSalesPerformanceLeaderEmail(userInfo, exportPath + File.separator + fileName, entity);
    }

    @Override
    public void tradePerformanceSendManagerReport(SalesPerformanceListEntity entity) throws Exception {
        List<TradeSalesPerformanceView> leaderViews = salesPerformanceMapper.pageSearch(entity);

        for (TradeSalesPerformanceView leaderView : leaderViews) {

            entity.setSalesNo(leaderView.getIbNo());
            List<TradeSalesPerformanceView> views = salesPerformanceMapper.salesPerformanceList(entity);

            TradeSalesPerformanceView sumView = salesPerformanceMapper.sumSearch(entity);

            UserInfoTable userInfo = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
            SalesLeaderTable leaderTable = salesLeaderRepository.getFirstBySalesNo(leaderView.getIbNo());
            List<TradeSalesPerformanceView> salesView = null;
            if (userInfo != null && userInfo.getStamp() != null && leaderTable != null) {
                entity.setStamp(userInfo.getStamp());
                entity.setLeaderId(userInfo.getLeaderId());
                salesView = salesPerformanceMapper.findAllSalesByStamp(entity);
            }

            String fileName = genFileName(userInfo.getIbNo());
//            List<TradeSalesPerformanceExportDto> dtos = convertToExportDto(views, salesView, sumView,
//                    userInfo == null ? null : userInfo.getAttachId(), userInfo == null ? null : userInfo.getId());

            if (CountryUtil.isCN(userInfo.getCountry())) {
                List<TradeSalesPerformanceExportDto> dtos = convertToExportDto(views, salesView, sumView,
                        userInfo.getAttachId(), userInfo.getId());
                ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                        TradeSalesPerformanceExportDto.class);
            } else {
                List<TradeSalesPerformanceExportEnDto> dtos = convertToExportEnDto(views, salesView, sumView,
                        userInfo.getAttachId(), userInfo.getId());
                ExportUtil.transferToFile(exportPath, fileName, userInfo.getIbNo(), dtos,
                        TradeSalesPerformanceExportEnDto.class);
            }
//            exportDtos.add(dtos);


//            ExportUtil.transferToFile(exportPath, fileName, sheetNameList, exportDtos,
//                    TradeSalesPerformanceExportDto.class);

            sendSalesPerformanceManagerEmail(userInfo, exportPath + File.separator + fileName, entity);
        }


    }

    @Override
    public void salesPerformanceStatistics(SalesPerformanceListEntity entity) throws Exception {
        mqSendService.send(Constants.SALES_PERFORMANCE_STATISTICS, entity);
    }

    @JmsListener(destination = Constants.SALES_PERFORMANCE_STATISTICS)
    @Transactional(rollbackFor = Exception.class)
    public void salesPerformanceStatistics(String content) throws Exception {
        log.info("销售业绩统计开始 ---------------");
        log.info(String.format("SALES_PERFORMANCE_STATISTICS,content:%s", content));
        SalesPerformanceListEntity entity = JSON.parseObject(content, SalesPerformanceListEntity.class);
        if (entity == null) {
            log.error("SALES_PERFORMANCE_STATISTICS,closeDate is null");
            return;
        }

        Date tradedMinDate = salesPerformanceMapper.getFirstDate();

        if (entity.getEndDate() == null || DateUtil.formatDate(entity.getEndDate()).compareTo(DateUtil.formatDate(new Date())) > 0) {
            entity.setEndDate(new Date());
        }
        if (entity.getStartDate() == null) {
            salesPerformanceTask(DateUtil.addDate(new Date(), -1), entity.getSalesNo());
        } else {
            if (DateUtil.formatDate(tradedMinDate).compareTo(DateUtil.formatDate(entity.getStartDate())) > 0) {
                entity.setStartDate(tradedMinDate);
            }

            for (int i = 0; i >= 0; i++) {
                Date statisticeDate = DateUtil.addDate(entity.getStartDate(), i);
                if (DateUtil.formatDate(statisticeDate).compareTo(DateUtil.formatDate(entity.getEndDate())) > 0) {
                    break;
                }
                salesPerformanceTask(statisticeDate, entity.getSalesNo());

            }
        }
        log.info("销售业绩统计结束 ---------------");
    }

    private void sendSalesPerformanceLeaderEmail(UserInfoTable userInfo, String path,
                                                 SalesPerformanceListEntity entity) throws ServiceException {
        if (userInfo == null) {
            return;
        }
        SysConfigTable sysConfigTable = sysConfigService.getByCode(Constants.SALES_PERFORMANCE_EMAIL);
        if (sysConfigTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        String rEmail = null;
        if (userInfo.getAttachId() != null) {
            UserInfoTable attachTable = userInfoRepository.getFirstById(userInfo.getAttachId());
            if (attachTable != null) {
                rEmail = attachTable.getEmail();
            }

        } else {
            rEmail = userInfo.getEmail();
        }
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(5);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.NAME, userInfo.getName());
        map.put(MapConstants.IB_NO, userInfo.getIbNo());
        map.put(MapConstants.V_START_TIME_V, DateUtil.formatDate(entity.getStartDate()));
        map.put(MapConstants.V_END_TIME_V, DateUtil.formatDate(entity.getEndDate()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG SALES PERFORMANCE LEADER");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.SALES_PERFORMANCE_LEADER);

        if (CountryUtil.isCN(userInfo.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.SALES_PERFORMANCE_LEADER_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.SALES_PERFORMANCE_LEADER_EN);
        }
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setUsers(rEmail);
        sysEmailSendEntity.setCcUsers(sysConfigTable.getValue());

        List<File> attachContentsList = new ArrayList<>();
        File file = new File(path);
        attachContentsList.add(file);
        sysEmailSendEntity.setAttachContentsList(attachContentsList);

        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendSalesPerformanceManagerEmail(UserInfoTable userInfo, String path,
                                                  SalesPerformanceListEntity entity) throws ServiceException {
        SysConfigTable sysConfigTable = sysConfigService.getByCode(Constants.SALES_PERFORMANCE_EMAIL);
        if (sysConfigTable == null || userInfo == null) {
            return;
        }

        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(4);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.NAME, userInfo == null ? "" : userInfo.getName());
        map.put(MapConstants.IB_NO, userInfo == null ? "" : userInfo.getIbNo());
        map.put(MapConstants.V_START_TIME_V, DateUtil.formatDate(entity.getStartDate()));
        map.put(MapConstants.V_END_TIME_V, DateUtil.formatDate(entity.getEndDate()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG SALES PERFORMANCE MANAGER");
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.SALES_PERFORMANCE_MANAGER);
//        sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.SALES_PERFORMANCE_MANAGER);
        sysEmailSendEntity.setUsers(sysConfigTable.getValue());

        if (CountryUtil.isCN(userInfo.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.SALES_PERFORMANCE_LEADER_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.SALES_PERFORMANCE_LEADER_EN);
        }
        List<File> attachContentsList = new ArrayList<>();
        File file = new File(path);
        attachContentsList.add(file);
        sysEmailSendEntity.setAttachContentsList(attachContentsList);

        try {
//            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<TradeSalesPerformanceDto> convertToDto(List<TradeSalesPerformanceView> views,
                                                        List<TradeSalesPerformanceView> salesView,
                                                        UserInfoTable userInfo) throws Exception {
        List<String> ibNo = new ArrayList<>();
        List<TradeSalesPerformanceDto> dtos = Lists.newArrayList();

        TradeSalesPerformanceDto leaderDto = null;
        for (TradeSalesPerformanceView view : views) {
            TradeSalesPerformanceDto dto = TradeSalesPerformanceDto.getInstance();
            BeanUtils.copyProperties(view, dto);
            dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));
            dto.setResignDate(DateUtil.formatDate(view.getResignDate()));
            if (userInfo != null && userInfo.getAttachId() != null && view.getSalesId().equals(userInfo.getAttachId())) {
                leaderDto = TradeSalesPerformanceDto.getInstance();
                BeanUtils.copyProperties(dto, leaderDto);
            } else {
                if (userInfo == null || !view.getSalesId().equals(userInfo.getId())) {
                    dtos.add(dto);
                }
            }
            ibNo.add(view.getIbNo());
        }

        if (salesView != null && salesView.size() > 0) {
            for (TradeSalesPerformanceView view : salesView) {
                if (ibNo.contains(view.getIbNo())) {
                    continue;
                }
                TradeSalesPerformanceDto dto = TradeSalesPerformanceDto.getInstance();
                dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));
                dto.setResignDate(DateUtil.formatDate(view.getResignDate()));
                dto.setLeaderName(userInfo.getName());
                dto.setIbNo(view.getIbNo());
                dto.setSalesName(view.getSalesName());
                dto.setCId(view.getCId());

                if (userInfo != null && userInfo.getAttachId() != null && view.getSalesId().equals(userInfo.getAttachId())) {
                    leaderDto = TradeSalesPerformanceDto.getInstance();
                    BeanUtils.copyProperties(dto, leaderDto);
                } else {
                    if (userInfo == null || !view.getSalesId().equals(userInfo.getId())) {
                        dtos.add(dto);
                    }
                }
            }
        }

        if (userInfo != null) {
            List<TradeSalesPerformanceDto> list = dtos.stream()
                    .sorted(Comparator.comparing((TradeSalesPerformanceDto p) -> p.getIbNo(),
                            Comparator.nullsLast(Comparator.naturalOrder())))
                    .collect(Collectors.toList());

            if (leaderDto != null) {
                list.add(0, leaderDto);
            }
            return list;
        } else {
            return dtos;
        }
    }

    private List<TradeSalesPerformanceExportDto> convertToExportDto(List<TradeSalesPerformanceView> views,
                                                                    List<TradeSalesPerformanceView> salesView,
                                                                    TradeSalesPerformanceView sumView, Long attachId,
                                                                    Long leaderId) throws Exception {
        List<String> ibNo = new ArrayList<>();
        List<TradeSalesPerformanceExportDto> dtos = Lists.newArrayList();

        TradeSalesPerformanceExportDto leaderDto = null;
        for (TradeSalesPerformanceView view : views) {
            TradeSalesPerformanceExportDto dto = TradeSalesPerformanceExportDto.getInstance();
            BeanUtils.copyProperties(view, dto);
            dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));

            if (null != attachId && view.getSalesId().equals(attachId)) {
                leaderDto = TradeSalesPerformanceExportDto.getInstance();
                BeanUtils.copyProperties(dto, leaderDto);
            } else {
                if (null == leaderId || !view.getSalesId().equals(leaderId)) {
                    dtos.add(dto);
                }
            }

            ibNo.add(view.getIbNo());
        }

        if (salesView != null && salesView.size() > 0) {
            for (TradeSalesPerformanceView view : salesView) {
                if (ibNo.contains(view.getIbNo())) {
                    continue;
                }
                TradeSalesPerformanceExportDto dto = TradeSalesPerformanceExportDto.getInstance();
                dto.setSalesName(view.getSalesName());
                dto.setIbNo(view.getIbNo());
                dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));

                if (null != attachId && view.getSalesId().equals(attachId)) {
                    leaderDto = TradeSalesPerformanceExportDto.getInstance();
                    BeanUtils.copyProperties(dto, leaderDto);
                } else {
                    if (null == leaderId || !view.getSalesId().equals(leaderId)) {
                        dtos.add(dto);
                    }
                }
            }
        }

        List<TradeSalesPerformanceExportDto> list = dtos.stream()
                .sorted(Comparator.comparing((TradeSalesPerformanceExportDto p) -> p.getIbNo(),
                        Comparator.nullsLast(Comparator.naturalOrder())))
                .collect(Collectors.toList());
        if (leaderDto != null) {
            list.add(0, leaderDto);
        }

        TradeSalesPerformanceExportDto sumDto = TradeSalesPerformanceExportDto.getInstance();
        BeanUtils.copyProperties(sumView, sumDto);
        list.add(sumDto);

        return list;
    }

    private List<TradeSalesPerformanceExportEnDto> convertToExportEnDto(List<TradeSalesPerformanceView> views,
                                                                        List<TradeSalesPerformanceView> salesView,
                                                                        TradeSalesPerformanceView sumView,
                                                                        Long attachId, Long leaderId) throws Exception {
        List<String> ibNo = new ArrayList<>();
        List<TradeSalesPerformanceExportEnDto> dtos = Lists.newArrayList();

        TradeSalesPerformanceExportEnDto leaderDto = null;
        for (TradeSalesPerformanceView view : views) {
            TradeSalesPerformanceExportEnDto dto = TradeSalesPerformanceExportEnDto.getInstance();
            BeanUtils.copyProperties(view, dto);
            dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));

            if (null != attachId && view.getSalesId().equals(attachId)) {
                leaderDto = TradeSalesPerformanceExportEnDto.getInstance();
                BeanUtils.copyProperties(dto, leaderDto);
            } else {
                if (null == leaderId || !view.getSalesId().equals(leaderId)) {
                    dtos.add(dto);
                }
            }

            ibNo.add(view.getIbNo());
        }

        if (salesView != null && salesView.size() > 0) {
            for (TradeSalesPerformanceView view : salesView) {
                if (ibNo.contains(view.getIbNo())) {
                    continue;
                }
                TradeSalesPerformanceExportEnDto dto = TradeSalesPerformanceExportEnDto.getInstance();
                dto.setSalesName(view.getSalesName());
                dto.setIbNo(view.getIbNo());
                dto.setEntryDate(DateUtil.formatDate(view.getEntryDate()));
                dto.setCID(view.getCId());

                if (null != attachId && view.getSalesId().equals(attachId)) {
                    leaderDto = TradeSalesPerformanceExportEnDto.getInstance();
                    BeanUtils.copyProperties(dto, leaderDto);
                } else {
                    if (null == leaderId || !view.getSalesId().equals(leaderId)) {
                        dtos.add(dto);
                    }
                }
            }
        }

        List<TradeSalesPerformanceExportEnDto> list = dtos.stream()
                .sorted(Comparator.comparing((TradeSalesPerformanceExportEnDto p) -> p.getIbNo(),
                        Comparator.nullsLast(Comparator.naturalOrder())))
                .collect(Collectors.toList());
        if (leaderDto != null) {
            list.add(0, leaderDto);
        }

        TradeSalesPerformanceExportEnDto sumDto = TradeSalesPerformanceExportEnDto.getInstance();
        BeanUtils.copyProperties(sumView, sumDto);
        list.add(sumDto);

        return list;

    }

    private String genFileName(String fileNamePrefix) {
        StringBuffer stringBuffer = new StringBuffer();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        stringBuffer.append(fileNamePrefix);
        stringBuffer.append("_");
        stringBuffer.append(sdf.format(new Date()));
        stringBuffer.append(".xlsx");
        String fileName = stringBuffer.toString();
        return fileName;
    }

}
