package com.crm.globex.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.globex.dao.mapper.AccountInfoMapper;
import com.crm.globex.dao.mapper.MTMapper;
import com.crm.globex.dao.repository.CustomInfoRepository;
import com.crm.globex.dao.repository.FinanceTransferRepository;
import com.crm.globex.service.FinanceTransferService;
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.FinanceBalanceToManagerEntity;
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.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.table.FinanceTransferTable;
import com.crm.rely.backend.model.pojo.view.CustomLoginView;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.DateUtil;
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.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class FinanceTransferServiceImpl implements FinanceTransferService {

    @Autowired
    private FinanceTransferRepository repository;

    @Autowired
    private AccountInfoMapper accountInfoMapper;
    @Autowired
    private CustomInfoRepository customInfoRepository;
    @Autowired
    private MTMapper mtMapper;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private EmailService emailService;

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

        FinanceTransferTable table = repository.findFirstByStatus(StatusConstants.APPLY_STATUS);
        if (table != null) {

            if (table.getSourceType() == null || table.getSourceType().equals(1)) {
                CustomLoginView accountInfoView =
                        accountInfoMapper.getAccountAmountByLoginAndPlatform(table.getWithdrawLogin(), "MT4");
                if (accountInfoView == null) {
                    table.setApproveUser(-1L);
                    table.setStatus(StatusConstants.REJECTED_STATUS);
                    table.setApproveTime(new Date());
                    table.setApproveDesc("103");
                    repository.save(table);
                    return;
                }

                //余额+浮动盈亏=实际的余额  -内转出金金额 如果小于0 表示客户金额不足 直接拒绝
                if ((accountInfoView.getBalance().add(accountInfoView.getFloating()).add(table.getAmount().negate())).compareTo(BigDecimal.ZERO) < 0) {
                    table.setApproveUser(-1L);
                    table.setStatus(StatusConstants.REJECTED_STATUS);
                    table.setApproveTime(new Date());
                    table.setApproveDesc("104");
                    repository.save(table);
                    return;
                }
            }

            table.setApproveUser(-1L);
            table.setStatus(StatusConstants.PASSED_STATUS);
            table.setApproveTime(new Date());
            table.setApproveDesc("100");

            table.setDepositStatus(StatusConstants.MANAGER_PENDING_STATUS);
            repository.save(table);
        }

    }

    /**
     * 内转入金
     *
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    public void scheduleAutomaticTransferDeposit() throws ServiceException {
        //查看 回调状态为成功 操作类型为自动入金 入金状态为正在入金中 审核状态为成功的订单
        FinanceTransferTable financeTransferTable =
                repository.findFirstByDepositStatusAndWithdrawStatusAndStatus(StatusConstants.MANAGER_PENDING_STATUS, StatusConstants.MANAGER_COMPLETED_STATUS, StatusConstants.PASSED_STATUS);

        if (financeTransferTable != null) {
            FinanceBalanceToManagerEntity financeBalanceToManagerEntity = new FinanceBalanceToManagerEntity();
            financeBalanceToManagerEntity.setAmount(financeTransferTable.getAmount());
            financeBalanceToManagerEntity.setComment(financeTransferTable.getSerial());
            financeBalanceToManagerEntity.setSerial(financeTransferTable.getSerial());
            financeBalanceToManagerEntity.setType(1);
            financeBalanceToManagerEntity.setLogin(financeTransferTable.getDepositLogin());
            financeBalanceToManagerEntity.setRouteType(Constants.TRADE_TRANS_TRANSFER_INFO);

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

            //设置入金状态为入金中
            financeTransferTable.setDepositStatus(StatusConstants.MANAGER_PROCESSING_STATUS);
            repository.save(financeTransferTable);
        }
    }

    /**
     * 内转出金
     *
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    public void scheduleAutomaticTransferWithdraw() throws ServiceException {
        //查看 回调状态为成功 操作类型为自动入金 入金状态为正在入金中 审核状态为成功的订单
        FinanceTransferTable financeTransferTable =
                repository.findFirstByDepositStatusAndWithdrawStatusAndStatus(StatusConstants.MANAGER_PENDING_STATUS, StatusConstants.MANAGER_PENDING_STATUS, StatusConstants.PASSED_STATUS);

        if (financeTransferTable != null) {

            CustomLoginView accountInfoView =
                    accountInfoMapper.getAccountAmountByLoginAndPlatform(financeTransferTable.getWithdrawLogin(), "MT4");

            FinanceBalanceToManagerEntity financeBalanceToManagerEntity = new FinanceBalanceToManagerEntity();
            financeBalanceToManagerEntity.setAmount(financeTransferTable.getAmount().negate());
            financeBalanceToManagerEntity.setComment(financeTransferTable.getSerial());
            financeBalanceToManagerEntity.setSerial(financeTransferTable.getSerial());
            financeBalanceToManagerEntity.setType(1);
            financeBalanceToManagerEntity.setLogin(financeTransferTable.getWithdrawLogin());
            financeBalanceToManagerEntity.setRouteType(Constants.TRADE_TRANS_TRANSFER_INFO);
            financeBalanceToManagerEntity.setFloating(accountInfoView.getFloating());

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

            //设置入金状态为出金中
            financeTransferTable.setWithdrawStatus(StatusConstants.MANAGER_PROCESSING_STATUS);
            repository.save(financeTransferTable);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticTransferAmount(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);
        }
        callbackAutomaticTransferAmount(callbackEntity.getCode(), callbackEntity.getData());
    }

    /**
     * 开始回调入金订单 manager成功失败
     *
     * @param entity
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    public void callbackAutomaticTransferAmount(Integer code, FinanceBalanceToManagerEntity entity) throws ServiceException {
        FinanceTransferTable financeTransferTable = repository.findFirstBySerial(entity.getSerial());

        if (financeTransferTable == null) {
            return;
        }
        Long order = null;
        if (entity.getOrder() == null || entity.getOrder().compareTo(0) <= 0) {
            //可以是因为调用api的返回的问题 根据条件-账号和备注去数据库查推送的订单数据 如果存在 则放回成功
            //如果不存在 则正常进行判断
            order = mtMapper.getOrder("MT4", entity.getLogin(), entity.getSerial());
        }
        if (order != null) {
            if (entity.getAmount().compareTo(BigDecimal.ZERO) > 0) {
                if (order != null) {
                    financeTransferTable.setDepositTicket(order.toString());
                    financeTransferTable.setDepositStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
                    sendCustomTransferEmail(financeTransferTable);
                } else {
                    financeTransferTable.setDepositTicket(null);
                    financeTransferTable.setDepositStatus(entity.getStatus());
                }
            } else if (entity.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                if (order != null) {
                    financeTransferTable.setWithdrawTicket(order.toString());
                    financeTransferTable.setWithdrawStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
                } else {
                    financeTransferTable.setWithdrawTicket(null);
                    financeTransferTable.setWithdrawStatus(entity.getStatus());
                }
            }
            return;
        }
        if (entity.getAmount().compareTo(BigDecimal.ZERO) > 0) {
            financeTransferTable.setDepositTicket(null);
            financeTransferTable.setDepositStatus(StatusConstants.MANAGER_PENDING_STATUS);

        } else if (entity.getAmount().compareTo(BigDecimal.ZERO) <= 0) {

            financeTransferTable.setWithdrawTicket(null);
            financeTransferTable.setWithdrawStatus(StatusConstants.MANAGER_PENDING_STATUS);
            if (!StatusConstants.MANAGER_COMPLETED_STATUS.equals(entity.getStatus())) {
                financeTransferTable = setStatus(financeTransferTable, code);
            }
        }

        repository.save(financeTransferTable);
    }

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


        return financeWithdrawTable;
    }


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

        switch (code.intValue()) {
            case -1000:
                financeWithdrawTable.setWithdrawStatus(null);
                financeWithdrawTable.setStatus(StatusConstants.REJECTED_STATUS);
                financeWithdrawTable.setApproveDesc("104");
                break;

            default:
                break;
        }
        return financeWithdrawTable;
    }

    private void sendCustomTransferEmail(FinanceTransferTable 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.NAME, table.getName());
        map.put(MapConstants.DEPOSIT_LOGIN, String.valueOf(table.getDepositLogin()));
        map.put(MapConstants.WITHDRAW_LOGIN, String.valueOf(table.getWithdrawLogin()));

        map.put(MapConstants.DEPOSIT_AMOUNT, table.getAmount() == null ? "" : String.format("%.2f", table.getAmount().doubleValue()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());

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

        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();
        }
    }


}
