package com.crm.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.pay.dao.mapper.FinanceTransferMapper;
import com.crm.pay.dao.repository.CustomInfoRepository;
import com.crm.pay.dao.repository.FinanceTransferRepository;
import com.crm.pay.service.CustomInfoService;
import com.crm.pay.service.CustomLoginService;
import com.crm.pay.service.FinanceTransferService;
import com.crm.pay.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.StatusConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
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.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.dto.finance.transfer.FinanceTransferSearchDto;
import com.crm.rely.backend.model.entity.finance.transfer.FinanceTransferAddEntity;
import com.crm.rely.backend.model.entity.finance.transfer.FinanceTransferDeleteEntity;
import com.crm.rely.backend.model.entity.finance.transfer.FinanceTransferSearchEntity;
import com.crm.rely.backend.model.entity.sys.config.SysConfigFinanceEntity;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.table.CustomLoginTable;
import com.crm.rely.backend.model.pojo.table.FinanceTransferTable;
import com.crm.rely.backend.model.pojo.view.FinanceTransferView;
import com.crm.rely.backend.model.util.CustomInfoUtil;
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.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FinanceTransferServiceImpl implements FinanceTransferService {
    @Autowired
    private FinanceTransferRepository financeTransferRepository;

    @Autowired
    private FinanceTransferMapper financeTransferMapper;

    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Autowired
    private CustomLoginService customLoginService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private MqSendService mqSendService;

    @Autowired
    private CustomInfoService customInfoService;

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

        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(entity.getCustomId());
        if (customInfoTable == null) {
            throw new ServiceException(Constants.FAIL);
        }

        String name = CustomInfoUtil.getName(customInfoTable);
        String orderNo = getOrderNo();

        //获取入金和出金的账户信息
        CustomLoginTable depositCustomLoginTable = null;
        CustomLoginTable withdrawCustomLoginTable = null;

        //如果是美金和人民币账户 则进行扣款
        /*if (entity.getSourceType().equals(2)) {
            customInfoService.updateUsdAmountById(entity.getCustomId(), entity.getAmount().negate(),
                    "内转->" + entity.getDepositLogin());
        }
        if (entity.getSourceType().equals(3)) {
            SysConfigFinanceEntity financeEntity = getConfigFinance();
            BigDecimal cnyAmount = entity.getAmount().multiply(financeEntity.getDepositRate());
            customInfoService.updateCnyAmountById(entity.getCustomId(), cnyAmount.negate(), "内转->" + entity.getDepositLogin());
        }*/

        List<Long> logins = new ArrayList<>(2);

        //如果是交易账户 则获取对应的交易账户
        if (entity.getSourceType().equals(1)) {
            logins.add(entity.getWithdrawLogin());
        }
        logins.add(entity.getDepositLogin());
        List<CustomLoginTable> customLoginTables = customLoginService.getByCustomIdAndLogins(entity.getCustomId(), logins);
        for (CustomLoginTable customLoginTable : customLoginTables) {
            if (customLoginTable.getLogin().equals(entity.getDepositLogin())) {
                depositCustomLoginTable = customLoginTable;
            } else if (customLoginTable.getLogin().equals(entity.getWithdrawLogin()) && entity.getSourceType().equals(1)) {
                withdrawCustomLoginTable = customLoginTable;
            }
        }
        if (depositCustomLoginTable == null || (entity.getSourceType().equals(1) && withdrawCustomLoginTable == null)) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        //以下为构建实体
        FinanceTransferTable financeTransferTable = new FinanceTransferTable();

        financeTransferTable.setAddIp(entity.getAddIp());
        financeTransferTable.setAddTime(entity.getAddTime());
        financeTransferTable.setAddUser(entity.getAddUser());

        financeTransferTable.setAmount(entity.getAmount());
        financeTransferTable.setCustomId(customInfoTable.getId());
        financeTransferTable.setName(name);
        financeTransferTable.setSerial(orderNo);
        financeTransferTable.setCId(entity.getCId());
        financeTransferTable.setDepositLogin(depositCustomLoginTable.getLogin());
        financeTransferTable.setDepositStatus(StatusConstants.MANAGER_PENDING_STATUS);
        financeTransferTable.setWithdrawLogin(withdrawCustomLoginTable != null ? withdrawCustomLoginTable.getLogin() : null);
        financeTransferTable.setStatus(StatusConstants.APPLY_STATUS);
        financeTransferTable.setSourceType(entity.getSourceType());
        if (entity.getSourceType().equals(1)) {
            financeTransferTable.setWithdrawStatus(StatusConstants.MANAGER_PENDING_STATUS);
        } else {
            financeTransferTable.setWithdrawStatus(StatusConstants.MANAGER_COMPLETED_STATUS);
        }

        financeTransferRepository.save(financeTransferTable);

        sendTransferEmail(financeTransferTable);

        return BaseResultDto.success();
    }

    /**
     * 发送出金申请邮件
     *
     * @param table
     * @throws ServiceException
     */
    private void sendTransferEmail(FinanceTransferTable table) throws ServiceException {

//        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_TRANSFER_EMAIL_NOTICE);
//        if (sysConfigTable == null) {
//            throw new ServiceException(Constants.SYSTEM_ERROR);
//        }
//        String users = sysConfigTable.getValue();
//
//        if (users == null) {
//            throw new ServiceException(Constants.SYSTEM_ERROR);
//        }
//        //构建map 用于后面邮件模版替换
//        Map<String, String> map = new HashMap<>(8);
//        map.put(MapConstants.C_ID, String.valueOf(table.getCId()));
//        map.put(MapConstants.NAME, table.getName());
//        map.put(MapConstants.SERIAL, table.getSerial());
//        map.put(MapConstants.APPLY_TIME, DateUtil.formatTime(table.getAddTime()));
//
//        map.put(MapConstants.DEPOSIT_LOGIN, table.getDepositLogin() + "");
//
//        map.put(MapConstants.WITHDRAW_LOGIN, table.getWithdrawLogin() + "");
//
//        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());
//
//        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
//        sysEmailSendEntity.setSubject("CWG TRANSFER");
//        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.FINANCE_TRANSFER_NOTICE);
//        sysEmailSendEntity.setMap(map);
//        sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.FINANCE_TRANSFER_NOTICE_NAME);
//        sysEmailSendEntity.setUsers(users);
//        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();
//        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(FinanceTransferDeleteEntity entity) throws ServiceException {
        List<FinanceTransferTable> allByIdIn = financeTransferRepository.findAllByIdIn(entity.getIds());
        if (allByIdIn == null || allByIdIn.size() <= 0) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        financeTransferRepository.delete(allByIdIn);
    }

    @Override
    public ResultWithPagerDto<FinanceTransferSearchDto> searchList(FinanceTransferSearchEntity entity) throws ServiceException {
        Integer count = financeTransferMapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<FinanceTransferView> financeTransferViews = financeTransferMapper.searchList(entity);

        if (financeTransferViews == null || financeTransferViews.size() <= 0) {

            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        List<FinanceTransferSearchDto> financeTransferSearchDtos = new ArrayList<>(financeTransferViews.size());

        for (FinanceTransferView financeTransferView : financeTransferViews) {
            FinanceTransferSearchDto transform = transform(financeTransferView);
            financeTransferSearchDtos.add(transform);
        }

        return ResultWithPagerDto.success(pageDto, financeTransferSearchDtos);
    }

    @Override
    public FinanceTransferSearchDto searchSingle(Long id) throws ServiceException {
        FinanceTransferView one = financeTransferMapper.getOne(id);
        if (one == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return transform(one);
    }

    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);
        String name = CustomInfoUtil.getName(customInfoTable);

        map.put(MapConstants.NAME, name);
        map.put(MapConstants.DEPOSIT_LOGIN, String.valueOf(table.getDepositLogin()));
        map.put(MapConstants.WITHDRAW_LOGIN, String.valueOf(table.getWithdrawLogin()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());

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

        sysEmailSendEntity.setTemplateName("CUSTOM_FINANCE_TRANSFER_NOTICE_NAME_CN");

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

    private FinanceTransferSearchDto transform(FinanceTransferView financeTransferView) {
        FinanceTransferSearchDto financeTransferSearchDto = new FinanceTransferSearchDto();
        BeanUtils.copyProperties(financeTransferView, financeTransferSearchDto);
        return financeTransferSearchDto;
    }

    private SysConfigFinanceEntity getConfigFinance() throws ServiceException {

        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_CONFIGURE);
        SysConfigFinanceEntity financeEntity = JSON.parseObject(sysConfigTable.getValue(), SysConfigFinanceEntity.class);
        if (financeEntity == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        return financeEntity;
    }

    private String getOrderNo() {
        /**
         * 生成订单号
         */
        String orderNo = GetRandom.getOrderNo(PayConstants.TRANSFER_HEAD);
        return orderNo;
    }
}
