package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.CustomKycApproveMapper;
import com.crm.manager.dao.repository.*;
import com.crm.manager.service.CustomKycApproveService;
import com.crm.manager.service.SysConfigService;
import com.crm.rely.backend.core.constant.*;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.custom.CustomKycApproveListDto;
import com.crm.rely.backend.core.dto.custom.file.CustomFileDto;
import com.crm.rely.backend.core.entity.base.BaseApproveEntity;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.custom.kyc.CustomKycApproveSearchEntity;
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.table.ucard.CardMerchantUserTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.util.*;
import com.google.common.collect.Lists;
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.*;

@Service
public class CustomKycApproveImpl implements CustomKycApproveService {

    @Autowired
    private CustomKycApproveRepository repository;
    @Autowired
    private CustomKycApproveMapper mapper;
    @Autowired
    private CustomFileRepository customFileRepository;
    @Autowired
    private CustomInfoRepository customInfoRepository;
    @Autowired
    private CustomBankRepository customBankRepository;
    @Autowired
    private CustomKycImageRepository customKycImageRepository;
    @Autowired
    private EmailService emailService;
    @Autowired
    private CardMerchantUsereRepository cardMerchantUsereRepository;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private CustomKycRemittanceChannelRepository kycRemittanceChannelRepository;


    @Override
    public ResultWithPagerDto<CustomKycApproveListDto> searchPageList(CustomKycApproveSearchEntity entity) throws ServiceException {
        Integer count = mapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<CustomKycApproveListDto> dtos = mapper.pageList(entity);

        if (dtos == null || dtos.size() <= 0) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        for (CustomKycApproveListDto dto : dtos) {
            dto.setName(CustomInfoUtil.getNameByCountry(dto.getFirstName(),dto.getLastName(),dto.getMiddle(),dto.getCountry()));
        }

        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    public CustomKycApproveListDto searchSingle(SingleLongEntity entity) throws ServiceException {
        CustomKycApproveListDto dto = mapper.getKycApproveById(entity.getId());
        if (dto == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        dto.setName(CustomInfoUtil.getNameByCountry(dto.getFirstName(),dto.getLastName(),dto.getMiddle(),dto.getCountry()));
        List<CustomKycImageTable> imagefiles =  customKycImageRepository.findByExternalUserId(dto.getExternalUserId());
        List<CustomFileDto> fileDtos = new ArrayList<>();
        for (CustomKycImageTable fileTable : imagefiles) {
            CustomFileDto fileDto = new CustomFileDto();
            fileDto.setPath(fileTable.getFileUrl());
            fileDto.setType(fileTable.getType());
            fileDtos.add(fileDto);
        }
        dto.setFiles(fileDtos);

        List<CustomFileTable> fileTables = customFileRepository.getAllByCustomId(dto.getCustomId());
        List<CustomFileDto> cardFilesDtos = Lists.newArrayList();
        for (CustomFileTable fileTable : fileTables) {
            CustomFileDto fileDto = new CustomFileDto();
            BeanUtils.copyProperties(fileTable, fileDto);
            cardFilesDtos.add(fileDto);
        }
        dto.setCardFiles(cardFilesDtos);

        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approve(BaseApproveEntity entity) throws ServiceException {
        CustomKycApproveTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (!Constants.APPLY_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception(Constants.CANNOT_APPROVE);
        }
        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(table.getCustomId());
        if (customInfoTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        BeanUtils.copyProperties(entity, table);

        if(Constants.PASSED_STATUS.equals(table.getStatus())){
            customInfoTable.setAuthStatus(1);
        }else{
            customInfoTable.setKycVerifyUrl(null);
            customInfoTable.setApplicantId(null);
        }
        customInfoRepository.save(customInfoTable);

        switch (table.getVerifyType()) {
            case 5:
                CustomBankTable bankTable = customBankRepository.findFirstById(table.getBankId());
                if (bankTable == null) {
                    throw ServiceException.exception(Constants.INFO_NOT_FOUND);
                }

                if(Constants.PASSED_STATUS.equals(table.getStatus())){
                    bankTable.setAuthStatus(1);

                    sendKycSuccessEmail(customInfoTable,bankTable);
                }else{
                    bankTable.setKycVerifyUrl(null);
                    bankTable.setApplicantId(null);

                    sendKycFailEmail(customInfoTable,bankTable);
                }
                customBankRepository.save(bankTable);
                break;

            case 6:
                CardMerchantUserTable merchantUserTable = cardMerchantUsereRepository.findFirstById(table.getBankId());
                if (merchantUserTable == null) {
                    throw ServiceException.exception(Constants.INFO_NOT_FOUND);
                }

                if(Constants.PASSED_STATUS.equals(table.getStatus())){
                    merchantUserTable.setAuthStatus(1);
                    // 邮件通知审核人员进行kyc手动审核
                    sendUcardKycApproveEmail(customInfoTable);
                }else{
                    merchantUserTable.setKycVerifyUrl(null);
                    merchantUserTable.setApplicantId(null);
                }
                cardMerchantUsereRepository.save(merchantUserTable);

                break;
            case 7:
                CustomKycRemittanceChannelTable channelTable = kycRemittanceChannelRepository.findFirstById(table.getBankId());
                if (channelTable == null) {
                    throw ServiceException.exception(Constants.INFO_NOT_FOUND);
                }
                if(Constants.PASSED_STATUS.equals(table.getStatus())){
                    channelTable.setAuthStatus(1);
                    channelTable.setVerifyNum(0);

                    // 邮件通知审核人员进行kyc手动审核
                    sendUcardKycApproveEmail(customInfoTable);
                }else{
                    channelTable.setKycVerifyUrl(null);
                    channelTable.setApplicantId(null);
                    channelTable.setVerifyNum(channelTable.getVerifyNum() == null?1:channelTable.getVerifyNum() + 1);
                    channelTable.setLastVerifyTime(new Date());
                }
                kycRemittanceChannelRepository.save(channelTable);
                break;
            default:
                break;
        }

        repository.save(table);
    }


    private void sendKycSuccessEmail(CustomInfoTable customInfoTable, CustomBankTable bankTable) throws ServiceException {
            Map<String, String> map = new HashMap<>(4);

            map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
            map.put(MapConstants.NAME, CustomInfoUtil.getName(customInfoTable));

            map.put(MapConstants.V_BLOCKCHAIN_NAME_V, bankTable.getAddressName());
            map.put(MapConstants.WALLET_ADDRESS, bankTable.getAddress());

            SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
            sysEmailSendEntity.setSubject("CWG CUSTOM KYC SUCCESS");
            sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_KYC_SUCCESS);
            sysEmailSendEntity.setMap(map);

            if (CountryUtil.isCN(customInfoTable.getCountry())) {
                sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_KYC_SUCCESS_CN);
            } else {
                sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_KYC_SUCCESS_EN);
            }
            sysEmailSendEntity.setUsers(customInfoTable.getEmail());

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

    /**
     * 通知管理员手动审核kyc认证
     */
    public void sendUcardKycApproveEmail(CustomInfoTable customInfoTable) throws ServiceException {
        // 审核人员邮箱
        SysConfigTable configTable = sysConfigService.getByCode(Constants.UCARD_KYC_APPROVE);
        if (configTable == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }

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

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.EMAIL, customInfoTable.getEmail());
        map.put(MapConstants.V_FIRST_NAME_V, customInfoTable.getFirstName());
        map.put(MapConstants.V_LAST_NAME_V, customInfoTable.getLastName());
        map.put(MapConstants.V_ENGLISH_NAME_V, customInfoTable.getNameEn());
        map.put(MapConstants.PHONE, customInfoTable.getPhone());
        map.put(MapConstants.C_ID, String.valueOf(customInfoTable.getCId()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG UCARD KYC APPROVE");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.UCARD_KYC_APPROVE);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.UCARD_KYC_APPROVE);
        sysEmailSendEntity.setUsers(configTable.getValue());

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

    private void sendKycFailEmail(CustomInfoTable customInfoTable, CustomBankTable bankTable) throws ServiceException {
        Map<String, String> map = new HashMap<>(4);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.NAME, CustomInfoUtil.getName(customInfoTable));

        map.put(MapConstants.V_BLOCKCHAIN_NAME_V, bankTable.getAddressName());
        map.put(MapConstants.WALLET_ADDRESS, bankTable.getAddress());

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG CUSTOM KYC FAIL");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_KYC_FAIL);
        sysEmailSendEntity.setMap(map);

        if (CountryUtil.isCN(customInfoTable.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_KYC_FAIL_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_KYC_FAIL_EN);
        }
        sysEmailSendEntity.setUsers(customInfoTable.getEmail());

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