package com.crm.ucard.service.impl;

import com.crm.rely.backend.core.constant.*;
import com.crm.rely.backend.core.entity.custom.info.*;
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.CustomInfoTable;
import com.crm.rely.backend.core.pojo.table.CustomLoginHistoryTable;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
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.service.MqSendService;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.*;
import com.crm.ucard.dao.repository.CardMerchantUserRepository;
import com.crm.ucard.dao.repository.CustomInfoRepository;
import com.crm.ucard.dao.repository.CustomLoginHistoryRepository;
import com.crm.ucard.service.CustomInfoService;
import com.crm.ucard.service.SysConfigService;
import com.crm.ucard.service.SysCustomBlackService;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: crm-backend
 * @description:
 * @author: houn
 * @create: 2019-07-25 16:14
 */
@SuppressWarnings("SpringJavaAutowiringInspection")
@Service
public class CustomInfoServiceImpl implements CustomInfoService {

    Logger logger = LoggerFactory.getLogger(CustomInfoServiceImpl.class);

    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Autowired
    private CustomLoginHistoryRepository customLoginHistoryRepository;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysCustomBlackService sysCustomBlackService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MqSendService mqSendService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private CardMerchantUserRepository merchantUsereRepository;


    /**
     * 用户登录
     *
     * @param entity
     * @return
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public InfoEntity login(CustomInfoLoginEntity entity) throws ServiceException {

        //首先用邮箱和密码验证账号
        CustomInfoTable customInfoTable = customInfoRepository.findFirstByEmailAndPassword(entity.getLoginName(), entity.getPassword());

        //如果不存在则判断 输入的是否为id
        if (customInfoTable == null) {
            Long id = null;
            try {
                //将登陆输入的账号转为id
                id = Long.parseLong(entity.getLoginName());
                customInfoTable = customInfoRepository.findFirstByIdAndPassword(id, entity.getPassword());
            } finally {
                //如果转化id异常或者id和密码不匹配 这提示用户名或密码错误
                if (customInfoTable == null || id == null) {
                    throw new ServiceException(Constants.LOGIN_FAIL);
                }
            }
        }
        logger.error("customInfoTable:" + customInfoTable.toString());

        if (!Strings.isNullOrEmpty(customInfoTable.getEmail())) {

            if (sysCustomBlackService.validateIdentity(customInfoTable.getIdentity()) || sysCustomBlackService.validateEmail(customInfoTable.getEmail())) {
                customInfoTable.setValid(0);
            }
        }
        /*
            获取ib信息
         */
        IbInfoEntity ibInfoEntity = null;
        /*IbLoginEntity ibLoginEntity = new IbLoginEntity();
        ibLoginEntity.setLoginName(customInfoTable.getEmail());
        try {
            SingleLongEntity singleLongEntity = new SingleLongEntity();
            singleLongEntity.setId(customInfoTable.getCId());
            logger.error("singleLongEntity:" + singleLongEntity.toString());
            BaseResultDto<IbInfoDto> ibInfoDtoBaseResultDto = ibInfoFeignService.getIbInfoByCid(singleLongEntity);
            logger.error("ibInfoDtoBaseResultDto:" + ibInfoDtoBaseResultDto.toString());
            IbInfoDto ibInfoDto = null;
            if (ibInfoDtoBaseResultDto.getCode() == Constants.SUCCESS_CODE) {
                ibInfoDto = ibInfoDtoBaseResultDto.getData();
                if (ibInfoDto != null) {
                    ibInfoEntity = new IbInfoEntity();
                    BeanUtils.copyProperties(ibInfoDto, ibInfoEntity);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }*/

        //CustomSurveyDto customSurveyDto = customSurveyService.getByCustomId(customInfoTable.getId());

        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.SHOP_SHOW);
        boolean isShop = false;
        if (sysConfigTable != null) {
            int shopShow = Integer.parseInt(sysConfigTable.getValue());
            if (shopShow >= 1) {
                isShop = true;
            }
        }

        InfoEntity transform = transform(customInfoTable, ibInfoEntity, entity,isShop);

        /**
         * 更新登录信息
         */
        customInfoTable.setLastAddress(entity.getAddress());
        customInfoTable.setLastIp(entity.getIp());
        customInfoTable.setLastTime(entity.getTime());
        customInfoTable.setModifyUser(customInfoTable.getId());
        customInfoTable.setModifyIp(entity.getIp());
        customInfoTable.setModifyTime(entity.getTime());
        customInfoRepository.save(customInfoTable);

        //添加登录记录
        CustomLoginHistoryTable customLoginHistoryTable = new CustomLoginHistoryTable();
        customLoginHistoryTable.setAddress(entity.getAddress());
        customLoginHistoryTable.setLoginIp(entity.getIp());
        customLoginHistoryTable.setLoginTime(entity.getTime());
        customLoginHistoryTable.setCustomId(customInfoTable.getId());
        customLoginHistoryTable.setName(customInfoTable.getFirstName() + customInfoTable.getMiddle() + customInfoTable.getLastName());
        customLoginHistoryTable.setAddUser(customInfoTable.getId());
        customLoginHistoryTable.setAddIp(entity.getIp());
        customLoginHistoryTable.setAddTime(entity.getTime());

        customLoginHistoryRepository.save(customLoginHistoryTable);

        return transform;
    }

    private InfoEntity transform(CustomInfoTable customInfoTable, IbInfoEntity ibInfoEntity, CustomInfoLoginEntity entity, boolean isShop) throws ServiceException {

        InfoEntity infoEntity = new InfoEntity();

        CustomInfoEntity customInfoEntity = new CustomInfoEntity();
        BeanUtils.copyProperties(customInfoTable, customInfoEntity);

        /*if(customInfoTable.getAuthStatus()==null || 1!=customInfoTable.getAuthStatus()){
            SysConfigTable sysConfigvrify = sysConfigService.getByCode(ConfigConstants.CUSTOM_VERIFY_KYC_PROPERTY);
            SysKycConfigTable kycConfig = sysKycConfigService.getByCodeAndCountryAndEnable(sysConfigvrify.getValue(),customInfoTable.getCountry(),1);
            if (kycConfig == null) {
                customInfoEntity.setAuthStatus(null);
            }else {
                customInfoEntity.setAuthStatus(0);
                customInfoEntity.setUploadImage(kycConfig.getUploadImage());
                customInfoEntity.setKycType(kycConfig.getKycType());
            }
        }*/

        CardMerchantUserTable table = merchantUsereRepository.findByCId(customInfoEntity.getCId());
        if (table != null) {
            customInfoEntity.setUniqueId(table.getUniqueId());
        }

        if (!Strings.isNullOrEmpty(customInfoTable.getExcludeShowLoginTypes())) {
            customInfoEntity.setExcludeShowLoginTypes(Arrays.asList(customInfoTable.getExcludeShowLoginTypes().split(",")));
        }

        if (!Strings.isNullOrEmpty(customInfoTable.getAddressLine())) {
            customInfoEntity.setAddressLines(Arrays.asList(customInfoTable.getAddressLine().split("@#")));
        }
        //默认返回到前端为0
        if (customInfoTable.getIbInvalid() == null) {
            customInfoEntity.setIbInvalid(0);
        }
        /*if (customSurveyDto != null) {
            BeanUtils.copyProperties(customSurveyDto, customInfoEntity);
        }*/
        infoEntity.setCustomInfo(customInfoEntity);
        infoEntity.setIbInfo(ibInfoEntity);

        infoEntity.setId(customInfoEntity.getId());
        infoEntity.setValid(customInfoEntity.getValid());
        infoEntity.setFirstName(customInfoEntity.getFirstName());
        infoEntity.setMiddle(customInfoEntity.getMiddle());
        infoEntity.setLastName(customInfoEntity.getLastName());
        infoEntity.setLang(customInfoTable.getLang());
        infoEntity.setThisAddress(entity.getAddress());
        infoEntity.setThisIp(entity.getIp());
        infoEntity.setThisTime(entity.getTime());

        if (ibInfoEntity == null) {
            infoEntity.setIsIb(false);
        } else {
            infoEntity.setIsIb(true);
        }
        infoEntity.setIsShop(isShop);

        return infoEntity;
    }

    /**
     * 未登录修改密码发送邮件
     */
    @Override
    public void updatePasswordSendEmail(CustomUpdatePasswordSendEmailEntity entity) throws ServiceException {

        CustomInfoTable customInfoTable = customInfoRepository.getFirstByEmailNotNullAndEmail(entity.getEmail());

        if (customInfoTable == null) {
            return;
//            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }
        SysEmailSendEntity sysEmailSendEntity = createUpdatePasswordSendEmailSysEmailEntity(entity, customInfoTable);

        redisService.save(sysEmailSendEntity.getMap().get(MapConstants.TOKEN), customInfoTable.getId(), Constants.EMAIL_TOKEN_TIME * 60 * 1000);

        mqSendService.send(Constants.ACTIVEMQ_JMS_URL_EMAIL, sysEmailSendEntity);

        //系统内部通知
        WebNoticeRecordAndEmailMqEntity mqEntity = new WebNoticeRecordAndEmailMqEntity(sysEmailSendEntity, customInfoTable.getCId());
        mqSendService.send(Constants.WEB_NOTICE_PUT_RECORD, mqEntity);
    }

    /**
     * 构建修改密码发送邮件实体
     *
     * @param entity
     * @param customInfoTable
     * @return
     */
    private SysEmailSendEntity createUpdatePasswordSendEmailSysEmailEntity(CustomUpdatePasswordSendEmailEntity entity, CustomInfoTable customInfoTable) {
        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        String token = AESUtil.encrypt(entity.getEmail() + Constants.LOGIN_LINK + UUIDUtil.getUUID() + Constants.LOGIN_LINK + customInfoTable.getId());
        Date time = DateUtil.operationMinute(new Date(), Constants.EMAIL_TOKEN_TIME);
        Map<String, String> map = new HashMap<>(4);
        String name = CustomInfoUtil.getName(customInfoTable);
        map.put(MapConstants.TOKEN, token);
        map.put(MapConstants.EXPIRE_TIME, DateUtil.formatTime(time));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());

        map.put(MapConstants.NAME, name);

        sysEmailSendEntity.setAddIp(entity.getIp());
        sysEmailSendEntity.setAddTime(entity.getTime());
        sysEmailSendEntity.setAddUser(customInfoTable.getAddUser());
        sysEmailSendEntity.setUsers(entity.getEmail());
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.FORGET_PASSWORD);
        if (CountryUtil.isCN(customInfoTable.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_UPDATE_PASSWORD_SEND_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_UPDATE_PASSWORD_SEND_EN);
        }
        sysEmailSendEntity.setMap(map);

        return sysEmailSendEntity;
    }

    /**
     * 未登录根据邮件修改密码
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(CustomUpdateEmailPasswordEntity entity) throws ServiceException {

        Long id = redisService.getEntity(entity.getToken(), Long.class);
        if (id == null) {
            throw new ServiceException("password_reset_link_has_expired");
        }

        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(id);

        if (customInfoTable == null) {
            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }

        /**
         * 填写修改时间和密码
         */
        customInfoTable.setPassword(entity.getPassword());
        customInfoTable.setModifyIp(entity.getModifyIp());
        customInfoTable.setModifyTime(entity.getModifyTime());
        customInfoTable.setModifyUser(customInfoTable.getModifyUser());

        customInfoRepository.save(customInfoTable);
        redisService.remove(entity.getToken());
        sendUpdatePasswordCompleteSendEmailSysEmailEntity(customInfoTable);
    }

    /**
     * @param customInfoTable
     */
    private void sendUpdatePasswordCompleteSendEmailSysEmailEntity(CustomInfoTable customInfoTable) throws ServiceException {
        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        Map<String, String> map = new HashMap<>(2);

        String name = CustomInfoUtil.getName(customInfoTable);
        map.put(MapConstants.NAME, name);
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());

        sysEmailSendEntity.setAddIp(customInfoTable.getModifyIp());
        sysEmailSendEntity.setAddTime(customInfoTable.getModifyTime());
        sysEmailSendEntity.setAddUser(customInfoTable.getAddUser());
        sysEmailSendEntity.setUsers(customInfoTable.getEmail());
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.FORGET_PASSWORD);
        if (CountryUtil.isCN(customInfoTable.getCountry())) {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_UPDATE_PASSWORD_COMPLETE_SEND_CN);
        } else {
            sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.CUSTOM_UPDATE_PASSWORD_COMPLETE_SEND_EN);
        }
        sysEmailSendEntity.setMap(map);

        emailService.sendEmail(sysEmailSendEntity);
    }

    @Override
    public BigDecimal getBalance(Long id) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(id);
        return customInfoTable.getBalance();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(CustomUpdateLoginPasswordEntity entity) throws ServiceException {

        CustomInfoTable customInfoTable = findFirstById(entity.getId());

        //验证密码是否正确
        if (!entity.getOldPassword().equals(customInfoTable.getPassword())) {
            throw new ServiceException(Constants.PASSWORD_ERROR);
        }
        /**
         * 填写修改时间和密码
         */
        customInfoTable.setPassword(entity.getNewPassword());
        customInfoTable.setModifyIp(entity.getModifyIp());
        customInfoTable.setModifyTime(entity.getModifyTime());
        customInfoTable.setModifyUser(entity.getModifyUser());

        customInfoRepository.save(customInfoTable);

        sendUpdatePasswordCompleteSendEmailSysEmailEntity(customInfoTable);
    }

    @Override
    public int getApplyReductionNum(Long customId) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(customId);
        return customInfoTable.getCardApplyReduction()==null?0:customInfoTable.getCardApplyReduction();
    }

    /**
     * 根据id获取用户信息
     *
     * @param id
     * @return
     */
    private CustomInfoTable findFirstById(Long id) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(id);

        if (customInfoTable == null) {
            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }
        return customInfoTable;
    }

}
