package com.yeejoin.amos.boot.module.tcm.biz.service.impl;

import com.yeejoin.amos.boot.module.tcm.api.common.CommonException;
import com.yeejoin.amos.boot.module.tcm.api.common.DesUtil;
import com.yeejoin.amos.boot.module.tcm.api.common.MobileLoginParam;
import com.yeejoin.amos.boot.module.tcm.api.enums.PhoneRegisterTypeEum;
import com.yeejoin.amos.boot.module.tcm.api.service.ISafetyService;
import com.yeejoin.amos.boot.module.tcm.biz.utils.RedisUtil;
import com.yeejoin.amos.boot.module.tcm.flc.api.feign.PrivilegeFeginService;
import com.yeejoin.amos.boot.module.tcm.flc.api.mapper.RegUnitInfoMapper;
import com.yeejoin.amos.component.feign.model.FeignClientResult;


import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.VerifyCodeAuthModel;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author cpp
 * @Description
 * @Date 2023/4/23
 */

@Slf4j
@Service
public class SafetyServiceImpl implements ISafetyService {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    RegUnitInfoMapper regUnitInfoMapper;

    @Resource
    SmallProServiceImpl smallProServiceImpl;

    private final int platformSuccessCode = 200;

    /**
     * 小程序端手机号验证码登录环境----方便在测试环境进行测试，不走平台的手机号验证码登录，直接走本地默认的 测试环境：dev 正式环境：product
     */

    private static final String loginEnvironment ="dev";
    /**
     * 产品appkey
     */
    private static final String appKey="AMOS_STUDIO";
    /**
     * 产品product
     */
    private static final String product="AMOS_STUDIO_WEB";
    /**
     * 是否放开微信管理员审核
     */

    private Boolean needWeChatAdminVerify =true;

    /**
     * redis key前缀prefixAuthCode
     */

    private static final String prefixAuthCode ="redis.key.prefix.authCode=REDIS_KEY_PREFIX_AUTH_CODE";


    /**
     * 微信管理员校验码
     */
    private final String fixedVerifyCode = "666666";
    @Autowired
    private PrivilegeFeginService privilegeFeginService;

    @Override
    public Map<String, Object> loginFromApp(MobileLoginParam param) {

            return loginFromAppProduct(param);
    }

    /**
     * 微信授权登录
     */
    private Map<String, Object> loginFromAppProduct(MobileLoginParam param) {
        // 初始化数据结构
        Map<String, Object> result = new HashMap<>();
        result.put("userInfo", new HashMap<>());
        result.put("authInfo", new HashMap<>());
        Map<String, Object> userInfo = new HashMap<>();
        Map<String, Object> authInfo = new HashMap<>();
        // 判断手机号
        if (ValidationUtil.isEmpty(param) || ValidationUtil.isEmpty(param.getPhoneNo())) {
            throw new CommonException(600001, "获取手机号失败!");
        }
       //验证手机号是否注册过
        VerifyCodeAuthModel model = new VerifyCodeAuthModel();
        model.setLoginId(param.getPhoneNo());
        model.setVerifyCode(DesUtil.encode(param.getPhoneNo(), param.getPhoneNo()));
        FeignClientResult<Map<String, String>> mobileVerifyCodeResult = new FeignClientResult<>();
        RequestContext.setToken("token");
        RequestContext.setProduct(product);
        RequestContext.setAppKey(appKey);
        mobileVerifyCodeResult=Privilege.authClient.mobileVerifyCode(model);
        if (mobileVerifyCodeResult.getStatus() != platformSuccessCode) {
            if (log.isErrorEnabled()) {
                log.error("调用平台手机号登录失败:{}", mobileVerifyCodeResult.getDevMessage());
            }
            throw new CommonException(600001, mobileVerifyCodeResult.getMessage());
        }
        // 设置authInfo信息
        authInfo.put("token", mobileVerifyCodeResult.getResult().get("token"));
        authInfo.put("personId", mobileVerifyCodeResult.getResult().get("userId"));
        authInfo.put("appKey", appKey);
        authInfo.put("product", product);
        result.put("authInfo", authInfo);
        // 设置userInfo信息
        RequestContext.setToken(mobileVerifyCodeResult.getResult().get("token"));
        FeignClientResult<AgencyUserModel> getme = Privilege.agencyUserClient.getme();
        getme.getResult().setPassword("");
        getme.getResult().setAppCodes(new ArrayList());
        result.put("userInfo", getme.getResult());
        return result;
    }


    /**
     * 手机号解析
     * @param param MobileLoginParam.class
     * @return String phoneNo
     */
    private String parsePhoneNo(MobileLoginParam param) {
        if (param.getRegisterType() == PhoneRegisterTypeEum.WX.getCode()) {
            // 进行验证码解析
            String encryptedData = param.getEncryptedData();
            String iv = param.getIv();
            String code = param.getCode();
            return smallProServiceImpl.getPhoneNumber(smallProServiceImpl.getSessionKey(code), encryptedData, iv);
        } else {
            return param.getPhoneNo();
        }
    }




    /**
     * 短信验证
     *
     * @param isNeedVerify 是否需要验证
     * @param verifyCode   验证码
     * @param phoneNo      手机号
     * @return 是否通过校验
     */
    private boolean smsVerifyCodeCheck(Boolean isNeedVerify, String verifyCode, String phoneNo) {
        if (fixedVerifyCode.equals(verifyCode) && needWeChatAdminVerify) {
            return true;
        }
        if (!isNeedVerify) {
            return true;
        }
        return this.checkVerifyCode(phoneNo, verifyCode);
    }

    private boolean checkVerifyCode(String phoneNo, String verifyCode) {
        String key = this.buildKey(prefixAuthCode, phoneNo);
        Object existVerifyCode = redisUtil.get(key);
        if (ObjectUtils.isEmpty(existVerifyCode)) {
            throw new CommonException(700001, "验证码已过期，请重新发起获取短信验证码请求！");
        }
        if (!verifyCode.equals(existVerifyCode)) {
            throw new CommonException(700001, "验证不通过");
        }
        redisUtil.del(key);
        return true;
    }


    private String buildKey(String prefixAuthCode, String phoneNo) {
        return prefixAuthCode + phoneNo;
    }


}
