package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.CustomLoginDao;
import com.crm.manager.dao.mapper.CustomLoginMarkDeleteMapper;
import com.crm.manager.dao.repository.*;
import com.crm.manager.service.CustomLoginDeleteRecordService;
import com.crm.manager.service.FinanceRateService;
import com.crm.rely.backend.core.constant.*;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.entity.custom.login.delete.record.CustomLoginDeleteRecordAddEntity;
import com.crm.rely.backend.core.entity.custom.wallet.history.CustomWalletHistoryAddEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.pojo.table.*;
import com.crm.rely.backend.core.pojo.view.CustomLoginView;
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.GetRandom;
import com.crm.rely.backend.util.UUIDUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class CustomLoginDeleteRecordServiceImpl implements CustomLoginDeleteRecordService {
    @Autowired
    private CustomLoginDeleteRecordRepository repository;

    @Autowired
    private CustomLoginMarkDeleteRepository customLoginMarkDeleteRepository;

    @Autowired
    private CustomLoginMarkDeleteMapper customLoginMarkDeleteMapper;

    @Autowired
    private MqSendService mqSendService;

    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Autowired
    private CustomLoginDao customLoginDao;

    @Autowired
    private CustomLoginDeleteRepository customLoginDeleteRepository;

    @Autowired
    private CustomLoginRepository customLoginRepository;

    @Autowired
    private EmailService emailService;

    @Autowired
    private FinanceRateService financeRateService;

    @Autowired
    private CustomWalletHistoryRepository customWalletHistoryRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto save(CustomLoginDeleteRecordAddEntity entity) throws Exception {

        //以下为构建实体
        CustomLoginDeleteRecordTable table = createCustomLoginDeleteRecord(entity);

        repository.save(table);

        return BaseResultDto.success();
    }

    @Override
    public BaseResultDto save(List<CustomLoginDeleteRecordAddEntity> entities) throws Exception {

        if (entities == null || entities.isEmpty()) {
            return BaseResultDto.success();
        }
        List<CustomLoginDeleteRecordTable> tables = new ArrayList<>(entities.size());
        for (CustomLoginDeleteRecordAddEntity entity : entities) {

            CustomLoginDeleteRecordTable table = createCustomLoginDeleteRecord(entity);
            tables.add(table);
        }

        repository.save(tables);

        return BaseResultDto.success();
    }

    private CustomLoginDeleteRecordTable createCustomLoginDeleteRecord(CustomLoginDeleteRecordAddEntity entity) {
        //以下为构建实体
        CustomLoginDeleteRecordTable table = new CustomLoginDeleteRecordTable();

        table.setAddIp(entity.getAddIp());
        table.setAddTime(entity.getAddTime());
        table.setAddUser(entity.getAddUser());
        table.setNote(entity.getNote());

        table.setCustomId(entity.getCustomId());
        table.setCId(entity.getCId());
        table.setCallbackMq(entity.getCallbackMq());
        table.setSerial(entity.getSerial());
        table.setPlatform(entity.getPlatform());
        table.setLogin(entity.getLogin());
        table.setDelStatus(Constants.MANAGER_PENDING_STATUS);
        return table;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void customLoginMarkDeleteTask() throws Exception {
        customLoginMarkDelete(Constants.MT4);
        customLoginMarkDelete(Constants.MT5);
    }

    @Transactional(rollbackFor = Exception.class)
    public void customLoginMarkDelete(String platform) throws Exception {

        //新开但未激活的休眠账户
        List<Long> acticveteDelList = customLoginMarkDeleteMapper.getNotActivateLoginList(platform);

        Boolean flag = true;
        //无持仓记录
        List<Long> positionList = customLoginMarkDeleteMapper.getPositionLoginList(platform);
        if (positionList == null || positionList.size() == 0) {
            flag = false;
        }

        //无挂单记录
        if (flag) {
            List<Long> pendingList = customLoginMarkDeleteMapper.getPendingLoginList(platform);
            getFlag(flag, positionList, pendingList);
        }

        //无平仓录
        if (flag) {
            String month1 = DateUtil.format("yyyyMM", new Date());
            String month2 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -1));
            String month3 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -2));
            String month4 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -3));
            String month5 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -4));
            String month6 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -5));
            String month7 = DateUtil.format("yyyyMM", DateUtil.addMonth(new Date(), -6));
            List<Long> historyList = customLoginMarkDeleteMapper.getHistoryLoginList(month1, month2, month3, month4,
                    month5, month6, month7, platform);
            getFlag(flag, positionList, historyList);
        }

        //无入金记录。
        if (flag) {
            List<Long> dwTradeList = customLoginMarkDeleteMapper.getDwTradeLoginList(platform);
            getFlag(flag, positionList, dwTradeList);
        }

        //账户余额为 0 或低于 10 美金，
        if (flag) {
            List<Long> balanceList = customLoginMarkDeleteMapper.getBalanceLoginList(positionList, platform);
            getFlag(flag, positionList, balanceList);
        }

        //需要标记删除的list
        positionList.addAll(acticveteDelList);
        List<Long> needMarkPositionList = positionList.stream().distinct().collect(Collectors.toList()); // 使用stream
        // 的distinct方法去除重复项

        //排除不需要删除的list
        List<Long> excludeList = customLoginMarkDeleteMapper.getCustomLoginDeleteExclude(platform);
        List<Long> needPositionList = needMarkPositionList.stream().filter(item -> !excludeList.contains(item))//去重
                .collect(Collectors.toList());

        //已标记删除的list
        List<Long> markList = customLoginMarkDeleteMapper.getCustomLoginMarkDeleteList(platform);

        //新增长期未交易的账户
        List<Long> tradeList = needPositionList.stream().filter(item -> !markList.contains(item))//去重
                .collect(Collectors.toList());
        if (tradeList != null && tradeList.size() > 0) {
            List<CustomLoginMarkDeleteTable> tradeDelList =
                    customLoginMarkDeleteMapper.getNotTradeLoginList(tradeList, platform);
            customLoginMarkDeleteRepository.save(tradeDelList);
            customLoginMarkDeleteMapper.batchUpdateCustomlogin(tradeList, true, new Date(), platform);

            List<CustomLoginView> emailTables = customLoginDao.getEmailCustomByLogin(tradeList, platform);
            sendMarkDeleteEmail(emailTables);
        }

        //已发生交易，删除标记
        List<Long> delMarkList = markList.stream().filter(item -> !needPositionList.contains(item))//去重
                .collect(Collectors.toList());
        if (delMarkList != null && delMarkList.size() > 0) {
            customLoginMarkDeleteMapper.delCustomloginMarkDelete(delMarkList, platform);
            customLoginMarkDeleteMapper.batchUpdateCustomlogin(delMarkList, false, null, platform);
        }

        //已标记删除15天的list
        List<Long> formalDeleteList = customLoginMarkDeleteMapper.getCustomLoginFormalDeleteList(platform);
        //正式删除的账户
        List<Long> formalDelList = needPositionList.stream().filter(formalDeleteList::contains)//取重
                .collect(Collectors.toList());
        if (formalDelList != null && formalDelList.size() > 0) {
            customLoginMarkDeleteMapper.batchUpdateCustomloginMarkFormalDel(formalDelList, platform);

            List<CustomLoginDeleteRecordAddEntity> recodeList =
                    customLoginMarkDeleteMapper.getCustomloginList(formalDelList, platform);
            for (CustomLoginDeleteRecordAddEntity entity : recodeList) {
                entity.setSerial(UUIDUtil.getUUID());
                entity.setCallbackMq(Constants.CUSTOM_LOGIN_MARK_DELETE);
            }
            mqSendService.send(Constants.CUSTOM_LOGIN_DELETE_INFOS, recodeList);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delCustomLogin(CustomLoginDeleteRecordTable table) throws Exception {
        CustomLoginMarkDeleteTable markDeleteTable =
                customLoginMarkDeleteMapper.getCustomLoginMarkDeleteByLogin(table.getLogin(), table.getPlatform());
        if (null == markDeleteTable) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }
        CustomLoginTable loginTable = customLoginRepository.getCustomLoginByLoginAndPlatform(table.getLogin(),
                table.getPlatform());
        if (null == loginTable) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }

        CustomInfoTable cunstomInfo = customInfoRepository.findFirstById(table.getCustomId());
        if (null != markDeleteTable.getBalance() && new BigDecimal(0).compareTo(new BigDecimal(markDeleteTable.getBalance())) < 0 &&
                new BigDecimal(10).compareTo(new BigDecimal(markDeleteTable.getBalance())) > 0) {
            BigDecimal balance = null == cunstomInfo.getBalance() ? new BigDecimal(0) : cunstomInfo.getBalance();
            BigDecimal markDeleteBalance = financeRateService.getRateAmount(loginTable.getCurrency(),
                    Constants.SYMBOL_USD, 1, new BigDecimal(markDeleteTable.getBalance()));
            cunstomInfo.setBalance(balance.add(markDeleteBalance));
            customInfoRepository.save(cunstomInfo);

            CustomWalletHistoryTable walletHistory = new CustomWalletHistoryTable();
            walletHistory.setSource(CustomWalletSourceEnum.TRANSFER.getCode());
            walletHistory.setCustomId(table.getId());
            walletHistory.setCId(table.getCId());
            walletHistory.setAmount(markDeleteBalance);
            walletHistory.setNote("delete login to wallet");
            customWalletHistoryRepository.save(walletHistory);

        }

        customLoginRepository.delete(loginTable);

        loginTable.setId(null);
        CustomLoginDeleteTable deleteTable = new CustomLoginDeleteTable();
        BeanUtils.copyProperties(loginTable, deleteTable);
        customLoginDeleteRepository.save(deleteTable);

        sendFormalDeleteEmail(loginTable, cunstomInfo);
    }

    public void getFlag(Boolean flag, List<Long> positionList, List<Long> list) {
        if (flag) {
            if (list != null && list.size() > 0) {
                positionList.retainAll(list);
            }

            if (positionList == null || positionList.size() == 0) {
                flag = false;
            }
        }
    }

    private void sendMarkDeleteEmail(List<CustomLoginView> views) throws ServiceException {
        for (CustomLoginView view : views) {
            //构建map 用于后面邮件模版替换
            Map<String, String> map = new HashMap<>(6);

            map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
            map.put(MapConstants.PLATFORM, view.getPlatform());
            map.put(MapConstants.C_ID, String.valueOf(view.getCId()));
            map.put(MapConstants.LOGIN, String.valueOf(view.getLogin()));
            map.put(MapConstants.NAME, view.getNameEn());

            SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
            sysEmailSendEntity.setSubject("CWG CUSTOM LOGIN MARK DELETE");
            sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_LOGIN_MARK_DELETE);
            sysEmailSendEntity.setMap(map);
            if (CountryUtil.isCN(view.getCountry())) {
                sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_LOGIN_MARK_DELETE_CN);
            } else {
                sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_LOGIN_MARK_DELETE_EN);
            }

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

    private void sendFormalDeleteEmail(CustomLoginTable loginTable, CustomInfoTable cunstomInfo) throws ServiceException {
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(6);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.PLATFORM, loginTable.getPlatform());
        map.put(MapConstants.C_ID, String.valueOf(loginTable.getCId()));
        map.put(MapConstants.LOGIN, String.valueOf(loginTable.getLogin()));
        map.put(MapConstants.NAME, cunstomInfo.getNameEn());

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG CUSTOM LOGIN FORMAL DELETE");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_LOGIN_MARK_DELETE);
        sysEmailSendEntity.setMap(map);

        if (CountryUtil.isCN(cunstomInfo.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_LOGIN_FORMAL_DELETE_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_LOGIN_FORMAL_DELETE_EN);
        }
        sysEmailSendEntity.setUsers(cunstomInfo.getEmail());
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private String getSerial() {
        String serial = GetRandom.getOrderNo(CustomConstant.CUSTOM_WALLET_HISTORY);
        return serial;
    }

    private CustomWalletHistoryTable getTable(CustomWalletHistoryAddEntity entity) {
        CustomWalletHistoryTable table = new CustomWalletHistoryTable();
        BeanUtils.copyProperties(entity, table);
        table.setSerial(getSerial());
        if (entity.getSource() != null) {
            table.setSource(entity.getSource().getCode());
        }
        return table;
    }


}
