package com.slodon.b2b2c.controller.member.front.advich;

import com.slodon.b2b2c.core.constant.RedisConst;
import com.slodon.b2b2c.core.constant.ResponseConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.i18n.Language;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.Md5;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.dao.read.member.MemberReadMapper;
import com.slodon.b2b2c.dao.write.member.MemberWriteMapper;
import com.slodon.b2b2c.enums.WebSiteConstant;
import com.slodon.b2b2c.member.example.MemberExample;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.model.member.MemberModel;
import com.slodon.b2b2c.model.member.advich.MemberEnquiryModel;
import com.slodon.b2b2c.model.member.advich.MemberRegisterActiveModel;
import com.slodon.b2b2c.model.seller.VendorModel;
import com.slodon.b2b2c.seller.dto.VendorRegisterDTO;
import com.slodon.b2b2c.system.dto.CountryAreaApiDto;
import com.slodon.b2b2c.vo.member.MemberDetailVO;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author cyan
 */
@Api(tags = "front-邮箱会员激活管理")
@RestController
@RequestMapping("v3/member/front/active")
@Slf4j
public class MemberEmailActiveController extends BaseController {

    @Resource
    private MemberRegisterActiveModel memberRegisterActiveModel;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private MemberReadMapper memberReadMapper;

    @Resource
    private MemberWriteMapper memberWriteMapper;

    @Resource
    private MemberModel memberModel;

    @Resource
    private MemberEnquiryModel memberEnquiryModel;

    @Resource
    private VendorModel vendorModel;

    private static final Map<Integer, String> EMAIL_KEY_MAP = new HashMap<>();

    private static final Map<Integer, String> MOBILE_KEY_MAP = new HashMap<>();

    static {
        EMAIL_KEY_MAP.put(1, RedisConst.SLD_PC_NEW_REGISTER_USER_EMAIL);
        EMAIL_KEY_MAP.put(2, RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL);
    }

    static {
        MOBILE_KEY_MAP.put(1, RedisConst.SLD_PC_NEW_REGISTER_USER_MOBILE);
        MOBILE_KEY_MAP.put(2, RedisConst.SLD_PC_FORGET_PWD_USER_MOBILE);
    }

//    /**
//     * @param request
//     * @param email
//     * @return
//     */
//    @GetMapping("/test")
//    public JsonResult<Object> sendEmailActiveLink(HttpServletRequest request, String email) {
//        if (StringUtil.isEmpty(email)) {
//            email = "cyan95@hotmail.com";
//        }
//        memberRegisterActiveModel.sendEmailActiveLink(email);
//        return SldResponse.success(Language.translate("发送验证邮件成功", Language.EN_LANGUAGE_TYPE));
//    }
//
//    /**
//     * @param request
//     * @param email
//     * @return
//     */
//    @GetMapping("/forget")
//    public JsonResult<Object> sendEmailForgetPasswordLink(HttpServletRequest request, String email) {
//        if (StringUtil.isEmpty(email)) {
//            email = "cyan95@hotmail.com";
//        }
//        memberRegisterActiveModel.sendEmailForgetPasswordLink(email, "cyan");
//        return SldResponse.success(Language.translate("发送验证邮件成功", Language.EN_LANGUAGE_TYPE));
//    }
//
//    /**
//     * @param request
//     * @param email
//     * @return
//     */
//    @GetMapping("/success")
//    public JsonResult<Object> sendRegisterSuccessEmail(HttpServletRequest request, String email) {
//        if (StringUtil.isEmpty(email)) {
//            email = "cyan95@hotmail.com";
//        }
//        memberRegisterActiveModel.sendRegisterSuccessEmail(email, "cyan");
//        return SldResponse.success(Language.translate("发送验证邮件成功", Language.EN_LANGUAGE_TYPE));
//    }
//
//    @GetMapping("/sms")
//    public JsonResult<Object> sendEnquirySms(HttpServletRequest request) {
//        memberEnquiryModel.sendEnquirySms(null);
//        return SldResponse.success();
//    }
//
//    @GetMapping("/sms/vendor")
//    public JsonResult<Object> sendVendorRegisterOkSms(HttpServletRequest request) {
//        VendorRegisterDTO vendorRegisterDTO = new VendorRegisterDTO();
//        vendorRegisterDTO.setVendorMobile("18762032916");
//        vendorModel.sendVendorRegisterOkSms(vendorRegisterDTO);
//        return SldResponse.success();
//    }

    /**
     * 发送用户邮箱注册链接
     *
     * @param request
     * @param email
     * @param source
     * @return
     */
    @PostMapping("/link")
    public JsonResult<Object> getMemberEmailLink(HttpServletRequest request, String email, Integer source) {
        log.info("getMemberEmailLink - email:{},source:{}", email, source);
        if (StringUtil.isEmpty(email)) {
            return SldResponse.fail("邮件不能为空");
        }
        AssertUtil.emailCheck(email);

        int count = memberRegisterActiveModel.sendRegisterUserEmail(email, source);
        AssertUtil.isTrue((count == 0), "发送验证邮件失败，请重试");
        AssertUtil.isTrue((count == 2), "该邮箱已注册，请登录");
        return SldResponse.success("发送验证邮件成功");
    }


    /**
     * 发送注册或忘记密码验证码
     *
     * @param request
     * @param email
     * @param source
     * @param type
     * @param mobile
     * @return
     */
    @PostMapping("/verification/code")
    public JsonResult<Object> getMemberEmailVerificationCode(HttpServletRequest request, String email, Integer source, Integer type, String mobile) {
        log.info("getMemberEmailVerificationCode - email:{},source:{},type:{},mobile:{}", email, source, type, mobile);
        String webSite = WebUtil.getWebSite(request);

        // 根据站点类型进行不同的处理
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            return handleVerificationCodeForOversea(webSite, email, mobile, source, type);
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            return handleVerificationCodeForDistributor(webSite, email, mobile, source, type);
        }

        return SldResponse.success("验证码发送成功");
    }

    /**
     * 处理海外站点验证码发送
     */
    private JsonResult<Object> handleVerificationCodeForOversea(String webSite, String email, String mobile, Integer source, Integer type) {
        if (StringUtil.isEmpty(email)) {
            return SldResponse.fail("邮件不能为空");
        }
        AssertUtil.emailCheck(email);

        return sendAndLimitVerificationCode(webSite, email, mobile, source, type,
                RedisConst.SLD_PC_EMAIL_VERIFY_CODE_LIMIT + email + ":type::" + type);
    }

    /**
     * 处理分销商站点验证码发送
     */
    private JsonResult<Object> handleVerificationCodeForDistributor(String webSite, String email, String mobile, Integer source, Integer type) {
        if (StringUtil.isEmpty(mobile)) {
            return SldResponse.fail("手机号码不能为空");
        }
        AssertUtil.mobileCheck(mobile);

        return sendAndLimitVerificationCode(webSite, email, mobile, source, type,
                RedisConst.SLD_PC_MOBILE_VERIFY_CODE_LIMIT + mobile + ":type::" + type);
    }

    /**
     * 发送验证码并设置频率限制
     */
    private JsonResult<Object> sendAndLimitVerificationCode(String webSite, String email, String mobile, Integer source,
                                                            Integer type, String redisKey) {
        // 1. 判断是否在1分钟内已发送过验证码
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(redisKey))) {
            return SldResponse.fail("请勿频繁操作，请1分钟后重试");
        }

        int count;
        if (type == 1) {
            count = memberRegisterActiveModel.sendRegisterUserVerificationCode(webSite, email, mobile, source);
            AssertUtil.isTrue((count == 0),"验证码发送失败，请重试");

            if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
                AssertUtil.isTrue((count == 2), "该邮箱已注册，请登录");
            } else {
                AssertUtil.isTrue((count == 2), "该手机号已注册，请登录");
            }
        } else {
            count = memberRegisterActiveModel.checkMemberUserInfo(webSite, email, mobile);
            AssertUtil.isTrue((count == 0),"验证码发送失败，请重试");

            if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
                AssertUtil.isTrue((count == 2), "该邮箱未激活，请先激活");
                AssertUtil.isTrue((count == 3), "该邮箱未注册，请先注册");
            } else {
                AssertUtil.isTrue((count == 2), "该手机号未激活，请先激活");
                AssertUtil.isTrue((count == 3), "该手机号未注册，请先注册");
            }
        }

        // 2. 设置 Redis 标记，1分钟内不可重复发送
        stringRedisTemplate.opsForValue().set(redisKey, "1", 60, TimeUnit.SECONDS);

        return SldResponse.success("验证码发送成功");
    }


    /**
     * 校验注册或忘记密码验证码
     *
     * @param request
     * @param email
     * @param type
     * @param verificationCode
     * @param mobile
     * @return
     */
    @PostMapping("/check/verification/code")
    public JsonResult<Object> checkMemberEmailVerificationCode(HttpServletRequest request, String email, Integer type, String verificationCode, String mobile) {
        log.info("checkMemberEmailVerificationCode - email:{},type:{},verificationCode:{},mobile:{}", email, type, verificationCode, mobile);
        String webSite = WebUtil.getWebSite(request);

        // 参数校验
        ValidationResult validation = validateVerificationParams(webSite, email, mobile, verificationCode);
        if (!validation.isValid()) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, validation.getErrorMessage());
        }

        // 根据站点类型进行验证码校验
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            return verifyCodeByEmail(email, type, verificationCode);
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            return verifyCodeByMobile(mobile, type, verificationCode);
        }

        return SldResponse.success("验证码校验成功");
    }


    /**
     * 通过邮箱验证验证码
     */
    private JsonResult<Object> verifyCodeByEmail(String email, Integer type, String verificationCode) {
        String baseKey = EMAIL_KEY_MAP.get(type);
        if (baseKey == null) {
            return SldResponse.fail("验证码不能为空");
        }

        String redisKey = baseKey + email;
        return verifyCodeFromRedis(redisKey, verificationCode);
    }

    /**
     * 通过手机号验证验证码
     */
    private JsonResult<Object> verifyCodeByMobile(String mobile, Integer type, String verificationCode) {
        String baseKey = MOBILE_KEY_MAP.get(type);
        if (baseKey == null) {
            return SldResponse.fail("验证码不能为空");
        }

        String redisKey = baseKey + mobile;
        return verifyCodeFromRedis(redisKey, verificationCode);
    }


    /**
     * 从Redis中验证验证码
     */
    private JsonResult<Object> verifyCodeFromRedis(String redisKey, String verificationCode) {
        if (!stringRedisTemplate.hasKey(redisKey)) {
            return SldResponse.fail("验证码校验失败");
        }

        String storedCode = stringRedisTemplate.opsForValue().get(redisKey);
        if (!verificationCode.equals(storedCode)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "验证码校验失败");
        }
        // 删除Redis中的验证码
        stringRedisTemplate.delete(redisKey);
        return SldResponse.success("验证码校验成功");
    }


    /**
     * 验证参数
     */
    private ValidationResult validateVerificationParams(String webSite, String email, String mobile, String verificationCode) {
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            if (StringUtil.isEmpty(email)) {
                return ValidationResult.invalid("邮件不能为空");
            }
            if (StringUtil.isEmpty(verificationCode)) {
                return ValidationResult.invalid("验证码不能为空");
            }
            AssertUtil.emailCheck(email);
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            if (StringUtil.isEmpty(mobile)) {
                return ValidationResult.invalid("手机号不能为空");
            }
            if (StringUtil.isEmpty(verificationCode)) {
                return ValidationResult.invalid("验证码不能为空");
            }
            AssertUtil.mobileCheck(mobile);
        }
        return ValidationResult.valid();
    }


    /**
     * 注册
     *
     * @param request
     * @param email
     * @param nickName
     * @param password
     * @param confirmPassword
     * @param mobile
     * @return
     */
    @PostMapping("/register")
    public JsonResult<Object> activeMemberEmailInfo(HttpServletRequest request, String email, String nickName, String password, String confirmPassword, String mobile) {
        log.info("activeMemberEmailInfo - email:{},nickName:{},password:{},confirmPassword:{},mobile:{}", email, nickName, password, confirmPassword, mobile);
        String webSite = WebUtil.getWebSite(request);
        // 参数校验和密码一致性检查
        ValidationResult validation = validateRegistrationParams(webSite, email, mobile, password, confirmPassword);
        if (!validation.isValid()) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, validation.getErrorMessage());
        }

        // 查找会员信息
        Member memberInfo = findMemberInfo(webSite, email, mobile);
        if (memberInfo == null) {
            String errorMsg = WebSiteConstant.MEMBER_OVERSEA.equals(webSite)
                    ? "会员邮箱不存在，请重新注册"
                    : "会员手机号不存在，请重新注册";
            return SldResponse.fail(ResponseConst.STATE_FAIL, errorMsg);
        }

        // 检查账户是否已激活
        if (isMemberAlreadyActive(memberInfo)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL,
                    "会员账号已激活，无需重复注册，请登录");
        }

        // 更新用户信息
        updateMemberInfo(request, memberInfo, nickName, password);

        // 发送成功通知
        return sendSuccessNotification(webSite, email, mobile, nickName);
    }

    /**
     * 验证注册参数
     */
    private ValidationResult validateRegistrationParams(String webSite, String email, String mobile,
                                                        String password, String confirmPassword) {
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            if (StringUtil.isEmpty(email)) {
                return ValidationResult.invalid("邮件不能为空");
            }
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            if (StringUtil.isEmpty(mobile)) {
                return ValidationResult.invalid("手机不能为空");
            }
            AssertUtil.mobileCheck(mobile);
        }

        if (!password.equals(confirmPassword)) {
            return ValidationResult.invalid("密码不一致，请重新输入");
        }

        AssertUtil.passwordCheck(password);
        return ValidationResult.valid();
    }

    /**
     * 查找会员信息
     */
    private Member findMemberInfo(String webSite, String email, String mobile) {
        MemberExample memberExample = new MemberExample();
        memberExample.setWebSite(webSite);

        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            memberExample.setMemberEmail(email.toLowerCase());
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            memberExample.setMemberMobile(mobile.toLowerCase());
        }

        List<Member> memberList = memberReadMapper.listByExample(memberExample);
        return CollectionUtils.isEmpty(memberList) ? null : memberList.get(0);
    }

    /**
     * 检查会员是否已激活
     */
    private boolean isMemberAlreadyActive(Member member) {
        return member.getIsEmailActive() != null && member.getIsEmailActive() == 1;
    }

    /**
     * 更新会员信息
     */
    private Member updateMemberInfo(HttpServletRequest request, Member memberInfo, String nickName, String password) {
        Member memberNew = new Member();
        memberNew.setMemberId(memberInfo.getMemberId());
        memberNew.setIsEmailActive(1);
        memberNew.setUpdateTime(new Date());
        memberNew.setMemberNickName(nickName);
        memberNew.setLoginPwd(Md5.getMd5String(password));

        String ip = WebUtil.getRealIp(request);
        CountryAreaApiDto countryAreaApiDto = memberEnquiryModel.getCountryAndAreaByIp(ip);
        memberNew.setCountry(countryAreaApiDto.getCountryIsoCode());
        memberNew.setCity(countryAreaApiDto.getCityIsoCode());
        memberNew.setLatitude(countryAreaApiDto.getLatitude());
        memberNew.setLongitude(countryAreaApiDto.getLongitude());

        memberModel.updateMember(memberNew);
        return memberNew;
    }

    /**
     * 发送成功通知
     */
    private JsonResult<Object> sendSuccessNotification(String webSite, String email, String mobile, String nickName) {
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            // 发送账户注册成功邮件
            memberRegisterActiveModel.sendRegisterSuccessEmail(email, nickName);
            return SldResponse.success("会员邮箱账户激活成功");
        } else {
            // 发送账户注册成功短信
            memberRegisterActiveModel.sendRegisterSuccessSms(mobile);
            return SldResponse.success("会员手机号激活成功");
        }
    }



    /**
     * 用户邮箱重置忘记密码
     *
     * @param request
     * @param email
     * @param verificationCode
     * @param loginPwd
     * @param confirmPassWord
     * @param mobile
     * @return
     */
    @PostMapping("/email/reset/pwdNew")
    public JsonResult<Object> emailResetPwdNew(HttpServletRequest request, String email, String verificationCode,
                                               String loginPwd, String confirmPassWord, String mobile) {
        log.info("emailResetPwd - email:{},verificationCode:{},loginPwd:{},confirmPassWord:{},mobile:{}",
                email, verificationCode, loginPwd, confirmPassWord, mobile);

        String webSite = WebUtil.getWebSite(request);

        // 参数校验
        ValidationResult validation = validateResetPasswordParams(webSite, email, mobile, loginPwd, confirmPassWord);
        if (!validation.isValid()) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, validation.getErrorMessage());
        }

        // 密码强度校验
        AssertUtil.passwordCheck(loginPwd);

        // 根据站点类型处理密码重置
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            return resetPasswordByEmail(webSite, email, verificationCode, loginPwd);
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            return resetPasswordByMobile(webSite, mobile, verificationCode, loginPwd);
        }

        return SldResponse.fail(ResponseConst.STATE_FAIL, "不支持的站点类型");
    }

    /**
     * 验证重置密码参数
     */
    private ValidationResult validateResetPasswordParams(String webSite, String email, String mobile,
                                                         String loginPwd, String confirmPassWord) {
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            if (StringUtil.isEmpty(email)) {
                return ValidationResult.invalid("邮件不能为空");
            }
        } else if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            if (StringUtil.isEmpty(mobile)) {
                return ValidationResult.invalid("手机不能为空");
            }
            AssertUtil.mobileCheck(mobile);
        }

        if (!loginPwd.equals(confirmPassWord)) {
            return ValidationResult.invalid("密码不一致，请重新输入");
        }

        return ValidationResult.valid();
    }

    /**
     * 通过邮箱重置密码
     */
    private JsonResult<Object> resetPasswordByEmail(String webSite, String email, String verificationCode, String loginPwd) {
        // 查找会员信息
        Member memberInfo = findMemberByEmail(webSite, email);
        if (memberInfo == null) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "该邮箱不存在，请先注册");
        }

        // 检查邮箱是否已激活
        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 0) {
            return SldResponse.fail(ResponseConst.STATE_FAIL,"该邮箱未激活，请先激活");
        }

        // 验证验证码并重置密码
        String forgetPwdEmailKey = RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL + email;
        return verifyCodeAndResetPassword(forgetPwdEmailKey, verificationCode, memberInfo, loginPwd);
    }

    /**
     * 通过手机号重置密码
     */
    private JsonResult<Object> resetPasswordByMobile(String webSite, String mobile, String verificationCode, String loginPwd) {
        // 查找会员信息
        Member memberInfo = findMemberByMobile(webSite, mobile);
        if (memberInfo == null) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "该手机号不存在，请先注册");
        }

        // 检查手机号是否已激活
        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 0) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "该手机号未激活，请先激活");
        }

        // 验证验证码并重置密码
        String forgetPwdMobileKey = RedisConst.SLD_PC_FORGET_PWD_USER_MOBILE + mobile;
        return verifyCodeAndResetPassword(forgetPwdMobileKey, verificationCode, memberInfo, loginPwd);
    }

    /**
     * 根据邮箱查找会员
     */
    private Member findMemberByEmail(String webSite, String email) {
        MemberExample memberExample = new MemberExample();
        memberExample.setMemberEmail(email.toLowerCase());
        memberExample.setWebSite(webSite);
        List<Member> memberList = memberReadMapper.listByExample(memberExample);
        return CollectionUtils.isEmpty(memberList) ? null : memberList.get(0);
    }

    /**
     * 根据手机号查找会员
     */
    private Member findMemberByMobile(String webSite, String mobile) {
        MemberExample memberExample = new MemberExample();
        memberExample.setMemberMobile(mobile.toLowerCase());
        memberExample.setWebSite(webSite);
        List<Member> memberList = memberReadMapper.listByExample(memberExample);
        return CollectionUtils.isEmpty(memberList) ? null : memberList.get(0);
    }

    /**
     * 验证验证码并重置密码
     */
    private JsonResult<Object> verifyCodeAndResetPassword(String redisKey, String verificationCode, Member memberInfo, String loginPwd) {
        log.info("forgetPwdKey:{}", redisKey);
        if (stringRedisTemplate.hasKey(redisKey)) {
            String verifyNumber = stringRedisTemplate.opsForValue().get(redisKey);
            log.info("verifyNumber:{}", verifyNumber);
            if (!verificationCode.equals(verifyNumber)) {
                return SldResponse.fail(ResponseConst.STATE_FAIL, "验证码校验失败");
            }

            // 更新用户密码
            Member memberNew = new Member();
            memberNew.setMemberId(memberInfo.getMemberId());
            memberNew.setLoginPwd(Md5.getMd5String(loginPwd));
            memberNew.setUpdateTime(new Date());
            Member member = memberModel.getMemberByMemberId(memberInfo.getMemberId());
            String newPassword =member.getLoginPwd();
            AssertUtil.isTrue(Md5.getMd5String(loginPwd).equals(newPassword), "新密码不能与上次密码一致!");
            memberModel.updateMember(memberNew);
            // 删除Redis中的验证码
            stringRedisTemplate.delete(redisKey);

            return SldResponse.success("重置登录密码成功");
        }
        return SldResponse.fail(ResponseConst.STATE_FAIL,"验证码校验失败");
    }



    /**
     * 用户邮箱链接激活
     *
     * @param request
     * @param email
     * @param code
     * @param verifyKey
     * @param verifyCode
     * @param nickName
     * @param password
     * @return
     */
    @PostMapping("/email")
    public JsonResult<Object> activeMemberEmailInfo(HttpServletRequest request, String email, String code, String verifyKey, String verifyCode, String nickName, String password) {
        log.info("activeMemberEmailInfo - email:{},code:{},verifyKey:{},verifyCode:{},nickName:{},password:{}", email, code, verifyKey, verifyCode, nickName, password);
        if (StringUtil.isEmpty(email) || StringUtil.isEmpty(code)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "注册链接不正确，请重新注册");
        }

        //获得redis中的验证码
        String verify_number = stringRedisTemplate.opsForValue().get(verifyKey);
        AssertUtil.isTrue(verify_number == null || !verify_number.equalsIgnoreCase(verifyCode), "图形验证码不正确");

        MemberExample memberExample = new MemberExample();
        memberExample.setMemberEmail(email.toLowerCase());
        List<Member> memberList = memberReadMapper.listByExample(memberExample);
        if (CollectionUtils.isEmpty(memberList)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "会员邮箱不存在，请重新注册");
        }

        Member memberInfo = memberList.get(0);
        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 1) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "会员邮箱已激活，无需重复注册，请登录");
        }

        String activeEmailKey = RedisConst.SLD_PC_NEW_REGISTER_USER_EMAIL + email;
        log.info("activeEmailKey:{}", activeEmailKey);
        if (stringRedisTemplate.hasKey(activeEmailKey)) {
            String verifyNumber = stringRedisTemplate.opsForValue().get(activeEmailKey);
            log.info("verifyNumber:{}", verifyNumber);
            if (!code.equals(verifyNumber)) {
                return SldResponse.fail(ResponseConst.STATE_FAIL,"注册链接激活码已失效，请重新注册");
            }

            // 更新用户邮箱激活状态
            Member memberNew = new Member();
            memberNew.setMemberId(memberInfo.getMemberId());
            memberNew.setIsEmailActive(1);
            memberNew.setUpdateTime(new Date());
            memberNew.setMemberNickName(nickName);
            memberNew.setLoginPwd(Md5.getMd5String(password));
            memberModel.updateMember(memberNew);

            stringRedisTemplate.delete(activeEmailKey);

            // 发送账户注册成功邮件
            memberRegisterActiveModel.sendRegisterSuccessEmail(email, nickName);

            return SldResponse.success("会员邮箱账户激活成功");
        }
        return SldResponse.fail(ResponseConst.STATE_FAIL, "注册链接已失效，请重新注册");
    }

    /**
     * 发送用户邮箱忘记密码链接
     *
     * @param request
     * @param email
     * @return
     */
    @PostMapping("/forget/pwd")
    public JsonResult<Object> getMemberEmailForgetPwdLink(HttpServletRequest request, String email, String verifyKey, String verifyCode) {
        log.info("getMemberEmailForgetPwdLink - email:{},verifyKey:{},verifyCode:{}", email, verifyKey, verifyCode);
        if (StringUtil.isEmpty(email)) {
            return SldResponse.fail("邮件不能为空");
        }
        AssertUtil.emailCheck(email);

        //获得redis中的验证码
        String verify_number = stringRedisTemplate.opsForValue().get(verifyKey);
        AssertUtil.isTrue(verify_number == null || !verify_number.equalsIgnoreCase(verifyCode), "图形验证码不正确");

        int count = memberRegisterActiveModel.checkMemberUserInfo(email);
        AssertUtil.isTrue((count == 0), "发送重置密码邮件失败，请重试");
        AssertUtil.isTrue((count == 2), "该邮箱未激活，请先激活");
        AssertUtil.isTrue((count == 3), "该邮箱未注册，请先注册");
        return SldResponse.success("重置密码链接已发送");
    }

    /**
     * 用户邮箱重置忘记密码
     *
     * @param request
     * @param email
     * @param code
     * @param loginPwd
     * @param verifyKey
     * @param verifyCode
     * @return
     */
    @PostMapping("/email/reset/pwd")
    public JsonResult<Object> emailResetPwd(HttpServletRequest request, String email, String code, String loginPwd, String verifyKey, String verifyCode) {
        log.info("emailResetPwd - email:{},code:{},loginPwd:{},verifyKey:{},verifyCode:{}", email, code, loginPwd, verifyKey, verifyCode);
        if (StringUtil.isEmpty(email) || StringUtil.isEmpty(code)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "重置密码链接不正确，请重新获取忘记密码链接");
        }

        //获得redis中的验证码
        String verify_number = stringRedisTemplate.opsForValue().get(verifyKey);
        AssertUtil.isTrue(verify_number == null || !verify_number.equalsIgnoreCase(verifyCode), "图形验证码不正确");

        MemberExample memberExample = new MemberExample();
        memberExample.setMemberEmail(email.toLowerCase());
        List<Member> memberList = memberReadMapper.listByExample(memberExample);

        if (CollectionUtils.isEmpty(memberList)) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "该邮箱不存在，请先注册");
        }

        Member memberInfo = memberList.get(0);
        if (memberInfo.getIsEmailActive() != null && memberInfo.getIsEmailActive() == 0) {
            return SldResponse.fail(ResponseConst.STATE_FAIL, "该邮箱未激活，请先激活");
        }

        String forgetPwdEmailKey = RedisConst.SLD_PC_FORGET_PWD_USER_EMAIL + email;
        log.info("forgetPwdEmailKey:{}", forgetPwdEmailKey);
        if (stringRedisTemplate.hasKey(forgetPwdEmailKey)) {
            String verifyNumber = stringRedisTemplate.opsForValue().get(forgetPwdEmailKey);
            log.info("verifyNumber:{}", verifyNumber);
            if (!code.equals(verifyNumber)) {
                return SldResponse.fail(ResponseConst.STATE_FAIL,"重置密码链接激活码已失效，请重新获取");
            }

            // 更新用户密码
            Member memberNew = new Member();
            memberNew.setMemberId(memberInfo.getMemberId());
            memberNew.setLoginPwd(Md5.getMd5String(loginPwd));
            memberNew.setUpdateTime(new Date());
            memberModel.updateMember(memberNew);

            stringRedisTemplate.delete(forgetPwdEmailKey);

            return SldResponse.success("重置登录密码成功");
        }
        return SldResponse.fail(ResponseConst.STATE_FAIL, "重置密码链接已失效，请重新获取");
    }

    private static class ValidationResult {
        private final boolean valid;
        private final String errorMessage;

        private ValidationResult(boolean valid, String errorMessage) {
            this.valid = valid;
            this.errorMessage = errorMessage;
        }

        static ValidationResult valid() {
            return new ValidationResult(true, null);
        }

        static ValidationResult invalid(String errorMessage) {
            return new ValidationResult(false, errorMessage);
        }

        public boolean isValid() {
            return valid;
        }

        public String getErrorMessage() {
            return errorMessage;
        }
    }
}
