package com.crm.globex.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.globex.configuration.MangerErrorSendEmailComponent;
import com.crm.globex.dao.repository.AccountApplyFirmOfferRepository;
import com.crm.globex.dao.repository.CustomInfoRepository;
import com.crm.globex.service.AccountApplyFirmOfferService;
import com.crm.globex.service.CustomLoginFirmOfferService;
import com.crm.globex.service.SysConfigService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.StatusConstants;
import com.crm.rely.backend.core.entity.manager.AccountToManagerEntity;
import com.crm.rely.backend.core.entity.manager.FinanceBalanceToManagerEntity;
import com.crm.rely.backend.core.entity.manager.callback.AccountCallbackEntity;
import com.crm.rely.backend.core.entity.manager.callback.FinanceCallbackEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.entity.web.notice.record.WebNoticeRecordAndEmailMqEntity;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.entity.custom.login.firm.offer.CustomLoginFirmOfferAddEntity;
import com.crm.rely.backend.model.entity.sys.config.SysMt4DomeConfigureEntity;
import com.crm.rely.backend.model.pojo.table.AccountApplyFirmOfferTable;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.GetRandom;
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.util.*;

/**
 * @description:
 * @author: houn
 * @create: 2020-07-31 23:06
 **/
@Service
public class AccountApplyFirmOfferServiceImpl implements AccountApplyFirmOfferService {
    @Autowired
    private MangerErrorSendEmailComponent toManagerErrorService;
    @Autowired
    private AccountApplyFirmOfferRepository accountApplyFirmOfferRepository;

    @Autowired
    private CustomLoginFirmOfferService customLoginFirmOfferService;

    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private MqSendService mqSendService;

    @Autowired
    private EmailService emailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void scheduleUpdateAccountOperationType() throws ServiceException {

        AccountApplyFirmOfferTable accountApplyFirmOfferTable =
                accountApplyFirmOfferRepository.findFirstByStatus(StatusConstants.APPLY_STATUS);
        if (accountApplyFirmOfferTable != null) {

            List<String> codes = new ArrayList<>(2);
            codes.add(ConfigConstants.AUTOMATIC_LOGON_LOGIN_MT4_FIRM_OFFER_NEXT);
            codes.add(ConfigConstants.AUTOMATIC_LOGON_LOGIN_MT4_FIRM_OFFER_CONFIGURE);
            List<SysConfigTable> sysConfigTables = sysConfigService.getByCodes(codes);

            SysMt4DomeConfigureEntity sysMt4DomeConfigureEntity = null;
            SysConfigTable nextLogin = null;
            for (SysConfigTable sysConfigTable : sysConfigTables) {
                if (ConfigConstants.AUTOMATIC_LOGON_LOGIN_MT4_FIRM_OFFER_CONFIGURE.equals(sysConfigTable.getCode())) {
                    sysMt4DomeConfigureEntity =
                            JSON.parseObject(sysConfigTable.getValue(), SysMt4DomeConfigureEntity.class);
                }
                if (ConfigConstants.AUTOMATIC_LOGON_LOGIN_MT4_FIRM_OFFER_NEXT.equals(sysConfigTable.getCode())) {
                    nextLogin = sysConfigTable;
                }
            }
            if (nextLogin == null || sysMt4DomeConfigureEntity == null) {
                //todo  通知管理员 系统出现问题
                accountApplyFirmOfferTable.setApproveUser(-1L);
                accountApplyFirmOfferTable.setApproveTime(new Date());
                accountApplyFirmOfferTable.setApproveDesc("103");
                accountApplyFirmOfferTable.setStatus(StatusConstants.REJECTED_STATUS);
                accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);
                return;
            }


            long login = 0;
            try {
                login = Long.parseLong(nextLogin.getValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
            //设置当前账号
            accountApplyFirmOfferTable.setLogin(login);
            //设置下一个账号保存
            login++;
            nextLogin.setValue(String.valueOf(login));
            String name = "SP" + DateUtil.format("MMddHHmmss");
            accountApplyFirmOfferTable.setName(name);
            accountApplyFirmOfferTable.setGroupCode(sysMt4DomeConfigureEntity.getGroupCode());
            accountApplyFirmOfferTable.setBalance(sysMt4DomeConfigureEntity.getBalance());
            int day =
                    sysMt4DomeConfigureEntity.getExpirationTimeDay() == null || sysMt4DomeConfigureEntity.getExpirationTimeDay() <= 0 ? 0 : sysMt4DomeConfigureEntity.getExpirationTimeDay();
            accountApplyFirmOfferTable.setExpirationTime(DateUtil.operationDay(new Date(), day));
            accountApplyFirmOfferTable.setLeverage(sysMt4DomeConfigureEntity.getLeverage());
            accountApplyFirmOfferTable.setCurrency(sysMt4DomeConfigureEntity.getCurrency());
            //设置状态为代修改中
            accountApplyFirmOfferTable.setAccountStatus(StatusConstants.MANAGER_PENDING_STATUS);
            accountApplyFirmOfferTable.setBalanceStatus(StatusConstants.MANAGER_PENDING_STATUS);
            //修改审核人  添加为系统审核
            accountApplyFirmOfferTable.setApproveUser(-1L);
            accountApplyFirmOfferTable.setApproveTime(new Date());
            accountApplyFirmOfferTable.setApproveDesc("100");
            accountApplyFirmOfferTable.setStatus(StatusConstants.PASSED_STATUS);

            accountApplyFirmOfferTable.setMasterPassword(GetRandom.getRandomPasswordString());
            accountApplyFirmOfferTable.setInvestorPassword(GetRandom.getRandomPasswordString());

            accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);
            sysConfigService.save(nextLogin);
        }

    }

    /**
     * 定时器 开始自动创建账户
     *
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void scheduleAutomaticAccount() throws ServiceException {
        //操作类型为自动 状态为正在待处理 审核状态为成功的订单
        AccountApplyFirmOfferTable accountApplyFirmOfferTable =
                accountApplyFirmOfferRepository.findFirstByAccountStatusAndBalanceStatusAndStatus(StatusConstants.MANAGER_PENDING_STATUS,
                        StatusConstants.MANAGER_PENDING_STATUS,
                        StatusConstants.PASSED_STATUS);


        if (accountApplyFirmOfferTable != null) {

            CustomInfoTable customInfoTable =
                    customInfoRepository.getFirstById(accountApplyFirmOfferTable.getCustomId());
            //如果找不到客户 直接显示系统异常
            if (customInfoTable == null) {
                accountApplyFirmOfferTable.setApproveUser(-1L);
                accountApplyFirmOfferTable.setApproveTime(new Date());
                accountApplyFirmOfferTable.setApproveDesc("103");
                accountApplyFirmOfferTable.setLogin(null);
                accountApplyFirmOfferTable.setGroupCode(null);
                accountApplyFirmOfferTable.setStatus(StatusConstants.REJECTED_STATUS);
                accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);
                return;
            }
            AccountToManagerEntity accountToManagerEntity = new AccountToManagerEntity();

            accountToManagerEntity.setSerial(accountApplyFirmOfferTable.getSerial());
            accountToManagerEntity.setName(accountApplyFirmOfferTable.getName());

            accountToManagerEntity.setLeverage(accountApplyFirmOfferTable.getLeverage());
            accountToManagerEntity.setLogin(accountApplyFirmOfferTable.getLogin());
            accountToManagerEntity.setGroup(accountApplyFirmOfferTable.getGroupCode());
            accountToManagerEntity.setMasterPass(accountApplyFirmOfferTable.getMasterPassword());
            accountToManagerEntity.setInvestorPass(accountApplyFirmOfferTable.getInvestorPassword());
            accountToManagerEntity.setLeadSource(accountApplyFirmOfferTable.getSerial());
            accountToManagerEntity.setRouteType(Constants.FIRM_OFFER_USER_RECORD_CREATE);
            accountToManagerEntity.setValid(1);

            accountApplyFirmOfferTable.setAccountStatus(StatusConstants.MANAGER_PROCESSING_STATUS);
            accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);

            mqSendService.send(Constants.MT4_USER_RECORD_CREATE, JSON.toJSONString(accountToManagerEntity));

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticAccount(AccountCallbackEntity callbackEntity) throws ServiceException {

        if (callbackEntity != null && callbackEntity.getCode() == Constants.SUCCESS_CODE && callbackEntity.getData() != null) {
            callbackEntity.getData().setStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
        } else {
            callbackEntity.getData().setStatus(StatusConstants.MANAGER_PENDING_STATUS);

            System.out.println("创建交易账户manager异常,callback data:" + callbackEntity);
        }
        callbackAutomaticAccount(callbackEntity.getCode(), callbackEntity.getData());
    }

    /**
     * 开始回调创建订单 manager成功失败
     *
     * @param entity
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticAccount(Integer code, AccountToManagerEntity entity) throws ServiceException {
        AccountApplyFirmOfferTable table = accountApplyFirmOfferRepository.findFirstBySerial(entity.getSerial());

        if (table == null) {
            return;
        }
        table.setAccountStatus(entity.getStatus());
        if (StatusConstants.MANAGER_COMPLETED_STATUS.equals(entity.getStatus())) {

            CustomLoginFirmOfferAddEntity customLoginAddEntity = new CustomLoginFirmOfferAddEntity();
            BeanUtils.copyProperties(table, customLoginAddEntity);
            customLoginAddEntity.setValid(entity.getValid());
            customLoginAddEntity.setName(entity.getName());
            customLoginAddEntity.setLoginStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
            customLoginAddEntity.setAddIp(table.getAddIp());
            customLoginAddEntity.setAddTime(new Date());
            customLoginAddEntity.setAddUser(table.getAddUser());
            customLoginFirmOfferService.add(customLoginAddEntity);

            //发送邮件
            sendCustomEmail(table);

        } else {
            table = setStatus(table, code);
            toManagerErrorService.addErrorInfo(code, Constants.FIRM_OFFER_USER_RECORD_CREATE, entity.getSerial(),
                    entity);
        }

        accountApplyFirmOfferRepository.save(table);
    }


    /**
     * 定时器 开始自动入金
     *
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void scheduleAutomaticAccountBalance() throws ServiceException {
        //操作类型为自动 状态为正在待处理 审核状态为成功的订单
        AccountApplyFirmOfferTable accountApplyFirmOfferTable =
                accountApplyFirmOfferRepository.findFirstByAccountStatusAndBalanceStatusAndStatus(StatusConstants.MANAGER_COMPLETED_STATUS,
                        StatusConstants.MANAGER_PENDING_STATUS,
                        StatusConstants.PASSED_STATUS);

        if (accountApplyFirmOfferTable != null) {

            FinanceBalanceToManagerEntity financeBalanceToManagerEntity = new FinanceBalanceToManagerEntity();
            financeBalanceToManagerEntity.setAmount(accountApplyFirmOfferTable.getBalance());
            financeBalanceToManagerEntity.setComment(accountApplyFirmOfferTable.getSerial());
            financeBalanceToManagerEntity.setSerial(accountApplyFirmOfferTable.getSerial());
            financeBalanceToManagerEntity.setType(1);
            financeBalanceToManagerEntity.setLogin(accountApplyFirmOfferTable.getLogin());
            financeBalanceToManagerEntity.setRouteType(Constants.FIRM_OFFER_TRADE_TRANS_INFO);

            mqSendService.send(Constants.MT4_TRADE_TRANS_INFO, JSON.toJSONString(financeBalanceToManagerEntity));

            accountApplyFirmOfferTable.setBalanceStatus(StatusConstants.MANAGER_PROCESSING_STATUS);
            accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticAccountBalance(FinanceCallbackEntity callbackEntity) throws ServiceException {

        if (callbackEntity != null && callbackEntity.getCode() == Constants.SUCCESS_CODE && callbackEntity.getData() != null) {
            callbackEntity.getData().setStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
        } else {
            callbackEntity.getData().setStatus(StatusConstants.MANAGER_PENDING_STATUS);

            System.out.println("模拟账户配置进而manager异常,callback data:" + callbackEntity);
        }
        callbackAutomaticAccountBalance(callbackEntity.getCode(), callbackEntity.getData());
    }

    /**
     * 开始回调创建订单 manager成功失败
     *
     * @param entity
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticAccountBalance(Integer code, FinanceBalanceToManagerEntity entity) throws ServiceException {
        AccountApplyFirmOfferTable accountApplyFirmOfferTable =
                accountApplyFirmOfferRepository.findFirstBySerial(entity.getSerial());

        if (accountApplyFirmOfferTable == null) {
            return;
        }
        accountApplyFirmOfferTable.setBalanceStatus(entity.getStatus());

        if (!StatusConstants.MANAGER_COMPLETED_STATUS.equals(entity.getStatus())) {
            toManagerErrorService.addErrorInfo(code, Constants.FIRM_OFFER_TRADE_TRANS_INFO, entity.getSerial(), entity);
        }

        accountApplyFirmOfferRepository.save(accountApplyFirmOfferTable);
    }

    private AccountApplyFirmOfferTable setStatus(AccountApplyFirmOfferTable accountApplyFirmOfferTable, Integer code) throws ServiceException {
        if (code == null) {
            code = 0;
        }
        accountApplyFirmOfferTable = setMT4Status(accountApplyFirmOfferTable, code);


        return accountApplyFirmOfferTable;
    }


    private AccountApplyFirmOfferTable setMT4Status(AccountApplyFirmOfferTable accountApplyFirmOfferTable,
                                                    Integer code) throws ServiceException {
        if (code == null) {
            code = 0;
        }

        switch (code.intValue()) {
            case -2:
                accountApplyFirmOfferTable.setAccountStatus(StatusConstants.MANAGER_PENDING_STATUS);
                SysConfigTable sysConfigTable = getLoginConfig();
                if (sysConfigTable == null) {
                    //todo  通知管理员 系统出现问题
                    throw ServiceException.exception(Constants.SYSTEM_ERROR);
                }
                long login = getLogin(sysConfigTable);
                //设置当前账号
                accountApplyFirmOfferTable.setLogin(login);
                //设置下一个账号保存
                login++;
                sysConfigTable.setValue(String.valueOf(login));
                sysConfigService.save(sysConfigTable);
                break;
//            case -65:
//                accountApplyFirmOfferTable.setAccountStatus(null);
//                accountApplyFirmOfferTable.setStatus(StatusConstants.REJECTED_STATUS);
//                accountApplyFirmOfferTable.setApproveDesc("101");
//                break;
            default:
                break;
        }
        return accountApplyFirmOfferTable;
    }

    private SysConfigTable getLoginConfig() throws ServiceException {
        SysConfigTable sysConfigTable = null;
        sysConfigTable = sysConfigService.getByCode(ConfigConstants.AUTOMATIC_LOGON_LOGIN_MT4_FIRM_OFFER_NEXT);

        return sysConfigTable;
    }


    private long getLogin(SysConfigTable sysConfigTable) throws ServiceException {
        if (sysConfigTable == null) {
            //todo 通知管理员
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        long login = 0;
        try {
            login = Long.parseLong(sysConfigTable.getValue());
        } catch (Exception e) {
            e.printStackTrace();
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        return login;
    }

    private void sendCustomEmail(AccountApplyFirmOfferTable table) throws ServiceException {

        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(table.getCustomId());
        if (customInfoTable == null) {
            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(10);

        map.put(MapConstants.LOGIN, String.valueOf(table.getLogin()));
        map.put(MapConstants.MASTER_PASSWORD, table.getMasterPassword());
        map.put(MapConstants.INVESTOR_PASSWORD, table.getInvestorPassword());
        map.put(MapConstants.C_ID, String.valueOf(table.getCId()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.LOGIN_TYPE, "实盘账户");

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG DEPOSIT");
        sysEmailSendEntity.setMap(map);

        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.ACCOUNT_FIRM_OFFER_CREATE_COMPLETE_SEND);

        sysEmailSendEntity.setUsers(customInfoTable.getEmail());
        try {
            emailService.sendEmail(sysEmailSendEntity);
            WebNoticeRecordAndEmailMqEntity mqEntity = new WebNoticeRecordAndEmailMqEntity(sysEmailSendEntity,
                    table.getCId(), table.getCustomId());
            mqSendService.send(Constants.WEB_NOTICE_PUT_RECORD, mqEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
