package org.jeecg.modules.userCode.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.shiro.ShiroRealm;
import org.jeecg.modules.bean.CodeBeanModel;
import org.jeecg.modules.bean.HttpConf;
import org.jeecg.modules.bean.LoginReq;
import org.jeecg.modules.hanHaiMember.entity.HanHaiMember;
import org.jeecg.modules.hanHaiMember.service.IHanHaiMemberService;
import org.jeecg.modules.postBean.ReqUserRole;
import org.jeecg.modules.postBean.ReqUserRole2;
import org.jeecg.modules.userCode.service.AppletLoginService;
import org.jeecg.modules.userRole.entity.TbUserRole;
import org.jeecg.modules.userRole.service.ITbUserRoleService;
import org.jeecg.modules.utils.ValidateTool;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class AppletLoginServiceImpl implements AppletLoginService {


    @Value("${wechat.mpAppId}")
    private String mpAppId;

    @Value("${wechat.mpAppSecret}")
    private String mpAppSecret;

    @Resource
    private ShiroRealm shiroRealm;

    @Resource
    private IHanHaiMemberService memberService;

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private HttpConf httpConf;
    @Resource
    private ITbUserRoleService tbUserRoleService;




    /**
     * 微信小程序登录接口
     * @param loginReq
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public Result<Object> appletLogin(LoginReq loginReq) {
        Result<Object> result = new Result<>();
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isBlank(loginReq.getCode())) {
            throw new JeecgBootException("小程序code为空");
        }
        String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + mpAppId + "&secret=" + mpAppSecret+ "&js_code=" + loginReq.getCode() + "&grant_type=authorization_code";
        //使用工具类
        JSONObject json_test = httpConf.getJSONObject(loginUrl);
        String wxOpenid = json_test.getString("openid");
        String sessionKey = json_test.getString("session_key");
        log.info("mpAppId{}=====mpAppSecret{}=====Code{}======wxOpenid{}",mpAppId,mpAppSecret,loginReq.getCode(),wxOpenid);
        if (StringUtils.isBlank(wxOpenid)) {
            throw new JeecgBootException("未获取到openid");
        }

        HanHaiMember member = memberService.lambdaQuery().eq(HanHaiMember::getAppletOpenid,wxOpenid).one();
        if (member == null) {
            //如果user等于null说明该用户第一次登录，数据库没有该用户信息。
            loginReq.setOpenid(wxOpenid);
            loginReq.setSession_key(sessionKey);
            member = new HanHaiMember();
//            member.setSesssionKey(sessionKey);
            member.setAppletOpenid(wxOpenid);
            member.setNickName(loginReq.getNickName());
            member.setHeadImage(loginReq.getHeadimgurl());
            // 生成token返回给小程序端
            String token = JwtUtil.sign(member.getAppletOpenid(), wxOpenid);
            memberService.save(member);
            redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
            // 设置超时时间
            redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 100);
            map.put("userInfo", member);
            map.put("token", token);
            //返回身份角色信息 新账号没有身份
            map.put("boss", null);
            map.put("company", null);
            map.put("worker", null);
            result.setCode(200);
            result.setResult(map);
            return result;
        } else {
//            member.setHeadImage(loginReq.getHeadimgurl());
//            member.setSessionKey(sessionKey);
//            memberService.saveOrUpdate(member);
            // 生成token返回给小程序端
            String token = JwtUtil.sign(member.getAppletOpenid(), wxOpenid);
            redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
            // 设置超时时间
            redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 100);
            Map roleInfo = tbUserRoleService.getRoleInfo(member.getId(),false);
            //返回身份角色信息
            map.put("boss", roleInfo.get("boss"));
            map.put("company", roleInfo.get("company"));
            map.put("worker", roleInfo.get("worker"));
            map.put("userInfo", member);
            map.put("token", token);
            //用户id做im账号
            result.setResult(map);
            result.setCode(200);
//            result.setMessage(member.getNickName()+"已于"+member.getCreateTime()+"注册成功！请勿重复注册！");
//            // 未绑定手机号，跳转授权绑定手机号
//            if (StringUtils.isBlank(member.getPhone())) {
//                result.setMessage("该微信用户尚未绑定手机号，请授权手机进行绑定");
//                result.setCode(905);
//                result.setResult(map);
//                return result;
//            }
        }

        return result;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<JSONObject> role2(ReqUserRole2 reqUserRole, String token) {
        HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiAccount(token);
        Result<JSONObject> result = new Result<JSONObject>();
        //getAuditStatus 0审核中 1 审核通过 2审核未通过
        LambdaQueryWrapper<TbUserRole> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(TbUserRole::getUserId,hanHaiMember.getId()).
                eq(TbUserRole::getRole,2).in(TbUserRole::getAuditStatus,1,0);
        TbUserRole one1 = tbUserRoleService.getOne(objectLambdaQueryWrapper);
        if (ValidateTool.isNotNull(one1) && one1.getAuditStatus()==0){
            return result.error500("已提交审核，请耐心等候或联系管理员");
        }
        if (ValidateTool.isNotNull(one1) && one1.getAuditStatus()==1){
            return result.error500("已提交审核，请勿重复提交");
        }
        TbUserRole tbUserRole = new TbUserRole();
        BeanUtils.copyProperties(reqUserRole, tbUserRole);
        tbUserRole.setUserId(hanHaiMember.getId());
        tbUserRole.setAuditStatus(0);
        tbUserRole.setRole(2);
        tbUserRoleService.save(tbUserRole);
        JSONObject obj = new JSONObject();
        obj.put("role", tbUserRole);
        result.setResult(obj);
        result.setCode(CommonConstant.SC_OK_200);
        return result;
    }

    /**
     * 小程序注册
     *
     * @param codeBeanModel
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> bindPhone(CodeBeanModel codeBeanModel) {
        Result<Object> result = new Result<>();
        String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + mpAppId + "&secret=" + mpAppSecret + "&js_code=" + codeBeanModel.getCode() + "&grant_type=authorization_code";
        try {
            CloseableHttpClient client = null;
            CloseableHttpResponse response = null;
            try {
                // 创建http GET请求
                HttpGet httpGet = new HttpGet(loginUrl);
                client = HttpClients.createDefault();
                // 执行请求
                response = client.execute(httpGet);
                HttpEntity entity = response.getEntity();//得到返回数据
                String resultStr = EntityUtils.toString(entity);
                JSONObject json_test = JSONObject.parseObject(resultStr);
                String wxOpenid = json_test.getString("openid");
                if (StringUtils.isEmpty(wxOpenid)) {
                    return result.error500("未获取到openid");
                }
                String sessionKey = json_test.getString("session_key");
                //根据id数据库数据查询
                HanHaiMember user = memberService.lambdaQuery().eq(HanHaiMember::getAppletOpenid,wxOpenid).one();
                if (user == null) {
                    return Result.error("用户信息查询失败，请");
                }

                // 保存sessionKey,用于解析手机号码
                codeBeanModel.setOpenid(wxOpenid);
                codeBeanModel.setSession_key(sessionKey);
                String userPhone = getPhoneNumber(codeBeanModel);
                if (StringUtils.isNotBlank(userPhone)) {
                    user.setPhone(userPhone);
                    HanHaiMember hanHaiMember = new HanHaiMember();
                    hanHaiMember.setId(user.getId());
                    hanHaiMember.setPhone(userPhone);
                    memberService.updateById(hanHaiMember);

                    result.setCode(200);
                    result.setMessage("手机号绑定成功");
                    // 返回用户信息给前台
                    BaseMap map = new BaseMap();
                    map.put("userInfo", user);
                    result.setResult(map);
                    return result;
                } else {
                    return Result.error("操作失败，请联系系统管理员！");
                }

            } finally {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("操作失败，请联系系统管理员！");
        }

    }




    //解析电话号码
    public String getPhoneNumber(CodeBeanModel codeBeanModel) {
        String encryptedData = codeBeanModel.getEncryptedData();
        String session_key = codeBeanModel.getSession_key();
        String iv = codeBeanModel.getIv();
        // 被加密的数据
        byte[] dataByte = Base64.decodeBase64(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decodeBase64(session_key);
        // 偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                log.warn("解析前{}",resultByte);
                log.warn("解析{}",result);
                JSONObject userPhoneObj = JSONObject.parseObject(result);
                Map<String, Object> userMap = new HashMap<>();
                for (Map.Entry<String, Object> entry : userPhoneObj.entrySet()) {
                    userMap.put(entry.getKey(), entry.getValue());
                }
                // 获取phoneNumber 带区号
                String userPhone = (String) userMap.get("phoneNumber");
                return userPhone;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<JSONObject> role(ReqUserRole reqUserRole, String token) {

        HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiAccount(token);
        Result<JSONObject> result = new Result<JSONObject>();
        //getAuditStatus 0审核中 1 审核通过 2审核未通过
        LambdaQueryWrapper<TbUserRole> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(TbUserRole::getUserId,hanHaiMember.getId()).
                eq(TbUserRole::getRole,reqUserRole.getRole()).in(TbUserRole::getAuditStatus,1,0);
        TbUserRole one1 = tbUserRoleService.getOne(objectLambdaQueryWrapper);
        if (ValidateTool.isNotNull(one1) && one1.getAuditStatus()==0){
            return result.error500("已提交审核，请耐心等候或联系管理员");
        }
        if (ValidateTool.isNotNull(one1) && one1.getAuditStatus()==1){
            return result.error500("已提交审核，请勿重复提交");
        }
        TbUserRole tbUserRole = new TbUserRole();
        BeanUtils.copyProperties(reqUserRole, tbUserRole);
        tbUserRole.setUserId(hanHaiMember.getId());
        tbUserRole.setAuditStatus(0);
        tbUserRoleService.save(tbUserRole);
        JSONObject obj = new JSONObject();
        obj.put("role", tbUserRole);
        result.setResult(obj);
        result.setCode(CommonConstant.SC_OK_200);
        return result;
    }


//    /**
//     * 微信小程序登录绑定手机号码接口
//     * @param loginReq
//     * @return
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public Result<Object> bindPhone(LoginReq loginReq) {
//        Result<Object> result = new Result<>();
//        if (StringUtils.isEmpty(loginReq.getEncryptedData())) {
//            result.setCode(500);
//            result.setMessage("请授权手机号");
//            return result;
//        }
//        String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + mpAppId + "&secret=" + mpAppSecret+ "&js_code=" + loginReq.getCode() + "&grant_type=authorization_code";
//        CloseableHttpClient client = null;
//        CloseableHttpResponse response = null;
//        try {
//            // 创建http GET请求
//            HttpGet httpGet = new HttpGet(loginUrl);
//            client = HttpClients.createDefault();
//            // 执行请求
//            response = client.execute(httpGet);
//            HttpEntity entity = response.getEntity();//得到返回数据
//            String resultStr = EntityUtils.toString(entity);
//            JSONObject json_test = JSONObject.parseObject(resultStr);
//            String wxOpenid = json_test.getString("openid");
//            if (StringUtils.isEmpty(wxOpenid)) {
//                return result.error500("未获取到openid");
//            }
//            String sessionKey = json_test.getString("session_key");
//            // 保存sessionKey,用于解析手机号码
//            loginReq.setOpenid(wxOpenid);
//            loginReq.setSession_key(sessionKey);
//            String userPhone = getPhoneNumber(loginReq);
//            HanHaiMember one = memberService.lambdaQuery().eq(HanHaiMember::getAppletOpenid, wxOpenid).one();
//            if(one!=null){
//                return result.OK("请不要重复注册");
//            }
//            HanHaiMember member = new HanHaiMember();
//            member.setSessionKey(sessionKey);
//            member.setAppletOpenid(wxOpenid);
//            member.setNickName(loginReq.getNickName());
//            member.setHeadImage(loginReq.getHeadimgurl());
//            member.setPhone(userPhone);
//
//
//            //判断用户是否存在
//            HanHaiMember boolOne = memberService.lambdaQuery().eq(HanHaiMember::getAccount, loginReq.geta()).one();
//            boolean bool = false;
//            if(one != null){
//                bool = true;
//            }
//
//            if(!bool){
//                member.setId(boolOne.getId());
//                memberService.updateById(member);
//            }else{
//                memberService.save(member);
//            }
//
//
//
//            return result.OK("注册成功",member);
//        }catch(Exception e) {
//            e.printStackTrace();
//            return Result.error("操作失败，请联系系统管理员！");
//        }
//
//    }
//
//
//
//    /**
//     * 解析电话号码
//     * @param loginReq
//     * @return
//     */
//    public String getPhoneNumber(LoginReq loginReq) {
//        String encryptedData = loginReq.getEncryptedData();
//        String session_key = loginReq.getSession_key();
//        String iv = loginReq.getIv();
//        // 被加密的数据
//        byte[] dataByte = Base64.decodeBase64(encryptedData);
//        // 加密秘钥
//        byte[] keyByte = Base64.decodeBase64(session_key);
//        // 偏移量
//        byte[] ivByte = Base64.decodeBase64(iv);
//        try {
//            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
//            int base = 16;
//            if (keyByte.length % base != 0) {
//                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
//                byte[] temp = new byte[groups * base];
//                Arrays.fill(temp, (byte) 0);
//                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
//                keyByte = temp;
//            }
//            // 初始化
//            Security.addProvider(new BouncyCastleProvider());
//            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
//            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
//            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
//            parameters.init(new IvParameterSpec(ivByte));
//            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
//            byte[] resultByte = cipher.doFinal(dataByte);
//            if (null != resultByte && resultByte.length > 0) {
//                String result = new String(resultByte, "UTF-8");
//                JSONObject userPhoneObj = JSONObject.parseObject(result);
//                Map<String, Object> userMap = new HashMap<>();
//                for (Map.Entry<String, Object> entry : userPhoneObj.entrySet()) {
//                    userMap.put(entry.getKey(), entry.getValue());
//                }
//                // 获取phoneNumber 带区号
//                String userPhone = (String) userMap.get("phoneNumber");
//                return userPhone;
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
}
