package com.ruoyi.framework.web.service;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wechat.AESUtils;
import com.ruoyi.common.utils.wechat.AccessTokenUtils;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.util.Objects;

/**
 * 登录校验方法
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class WechatService {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysUserServiceImpl sysUserService;

    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;
    //发送模板路径
    @Value("${wechat.templateMsgUrl}")
    private String templateMsgUrl;
    // 模板id
    //@Value("${wechat.templateId}")
   // private String templateId;


    /**
     * 微信生成token
     *
     * @param loginBody code
     * @return 结果
     */
    public AjaxResult login(LoginBody loginBody) {
        if(StringUtils.isNotEmpty(loginBody.getUsertype()) && loginBody.getUsertype().equals("00")){
            if (StringUtils.isNotEmpty(loginBody.getToken())) {
                // 仅仅获取token
                SysUser sysUser = sysUserService.selectUserByPhone(loginBody,"00");
                if (StringUtils.isNull(sysUser)) {
                    return AjaxResult.error("未找到用户信息，请确认");
                }
                // 生成token
                LoginUser loginUser = new LoginUser();
                loginUser.setUser(sysUser);
                String token = tokenService.wechatCreateToken(loginUser);
                if (StringUtils.isEmpty(token)) {
                    return AjaxResult.error("生成token失败");
                }
                LoginBody body = new LoginBody();
                body.setToken(token);
                body.setPhonenumber(sysUser.getPhonenumber());
                return AjaxResult.success(body);
            }
            // 获取openId、sessionKey
            SysUser user = sysUserService.weChatProgramLogin(loginBody,"00");
            if (StringUtils.isNull(user)) {
                return AjaxResult.error("获取OpenId失败");
            }
            // 解密获取手机号
            try {
                String dataType = "phoneNumber";
                AjaxResult ajaxResult = decodeUserInfo(loginBody.getPhonenumber(), loginBody.getIv(), user.getSessionKey(), dataType);
                String code = ajaxResult.get("code").toString();
                if ("500".equals(code)) {
                    return ajaxResult;
                }
                user.setPhonenumber(ajaxResult.get("data").toString());
            } catch (UnsupportedEncodingException e) {
                log.info("解析手机号UnsupportedEncodingException异常：" + e);
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                log.info("解析手机号InvalidAlgorithmParameterException异常：" + e);
                e.printStackTrace();
            }
            LoginUser loginUser = sysUserService.warehouseCreateOrUpdateUser(user);
            if (StringUtils.isNull(loginUser)) {
                return AjaxResult.error("未找到用户信息");
            }
            // 生成token
            String token = tokenService.wechatCreateToken(loginUser);
            if (StringUtils.isEmpty(token)) {
                return AjaxResult.error("生成token失败");
            }
            LoginBody body = new LoginBody();
            body.setToken(token);
            body.setPhonenumber(user.getPhonenumber());
            return AjaxResult.success(body);
        }else{
            if (StringUtils.isNotEmpty(loginBody.getToken())) {
                // 仅仅获取token
                SysUser sysUser = sysUserService.selectUserByPhone(loginBody,"11");
                if (StringUtils.isNull(sysUser)) {
                    return AjaxResult.error("未找到用户信息，请确认");
                }
                // 生成token
                LoginUser loginUser = new LoginUser();
                loginUser.setUser(sysUser);
                String token = tokenService.wechatCreateToken(loginUser);
                if (StringUtils.isEmpty(token)) {
                    return AjaxResult.error("生成token失败");
                }
                LoginBody body = new LoginBody();
                body.setToken(token);
                body.setPhonenumber(sysUser.getPhonenumber());
                return AjaxResult.success(body);
            }
            // 获取openId、sessionKey
            SysUser user = sysUserService.weChatProgramLogin(loginBody,"11");
            if (StringUtils.isNull(user)) {
                return AjaxResult.error("获取OpenId失败");
            }
            // 解密获加密信息
            try {
                String dataType = "phoneNumber";
                AjaxResult ajaxResult = decodeUserInfo(loginBody.getPhonenumber(), loginBody.getIv(), user.getSessionKey(), dataType);
                String code = ajaxResult.get("code").toString();
                if ("500".equals(code)) {
                    return ajaxResult;
                }
                user.setPhonenumber(ajaxResult.get("data").toString());
                dataType = "unionId";
                AjaxResult result = decodeUserInfo(loginBody.getEncryptedData(), loginBody.getEncryptedIv(), user.getSessionKey(), dataType);
                String code1 = result.get("code").toString();
                if ("500".equals(code1)) {
                    return result;
                }
                user.setUnionId(result.get("data").toString());
            } catch (UnsupportedEncodingException e) {
                log.info("解析手机号UnsupportedEncodingException异常：" + e);
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                log.info("解析手机号InvalidAlgorithmParameterException异常：" + e);
                e.printStackTrace();
            }
            LoginUser loginUser = sysUserService.createOrUpdateUser(user);
            if (StringUtils.isNull(loginUser)) {
                return AjaxResult.error("未找到用户信息");
            }
            // 生成token
            String token = tokenService.wechatCreateToken(loginUser);
            if (StringUtils.isEmpty(token)) {
                return AjaxResult.error("生成token失败");
            }
            LoginBody body = new LoginBody();
            body.setToken(token);
            body.setPhonenumber(user.getPhonenumber());
            return AjaxResult.success(body);
        }
    }

    /**
     * 解密小程序用户敏感数据（暂时用于解密手机号）
     * https://blog.csdn.net/weixin_42771651/article/details/107359620
     *
     * @param encryptedData 明文
     * @param iv            加密算法的初始向量
     * @param sessionKey    用户秘钥
     * @return 结果
     */
    public AjaxResult decodeUserInfo(String encryptedData, String iv, String sessionKey, String dataType
    ) throws UnsupportedEncodingException, InvalidAlgorithmParameterException, JSONException {
        //AESUtils微信获取手机号解密工具类
        AESUtils aes = new AESUtils();
        //调用AESUtils工具类decrypt方法解密获取json串
        byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
        //判断返回参数是否为空
        if (null != resultByte && resultByte.length > 0) {
            String jsons = new String(resultByte, "UTF-8");
            JSONObject json = JSONObject.parseObject(jsons);
            System.out.println("跟手机号同级别数据：" + json.toString());
            //json解析phoneNumber值
            String phoneNumber = json.getString(dataType);
            if (StringUtils.isEmpty(phoneNumber)) {
                log.info("解析加密异常：" + json.toJSONString());
                return AjaxResult.error("解析加密异常");
            }
            return AjaxResult.success("操作成功", phoneNumber);
        }
        return AjaxResult.error(500, "session_key:失败");
    }

    /**
     * 发送模板消息
     *
     * @param fromUser  接收此消息的openId
     * @param mblno     提单号
     * @param route     路线
     * @param goodsName 商品名
     * @param loadDate  装货时间
     * @return 结果
     */
    public Objects newsPush(String fromUser, String mblno, String route, String goodsName, String loadDate) {
        String jsonBody = "{\n" +
                "  \"touser\": \"" + fromUser + "\",\n" +
                "  \"template_id\": \"PkeerRaAwBYrwvvrbKrXiGzYok0tehLa9huVxQ6vkco\",\n" +
                "  \"url\": \"\",\n" +
                "  \"data\": {\n" +
                "    \"first\": {\n" +
                "      \"value\": \"靖润\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    },\n" +
                "    \"keyword1\": {\n" +
                "      \"value\": \"" + mblno + "\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    },\n" +
                "    \"keyword2\": {\n" +
                "      \"value\": \"" + route + "\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    },\n" +
                "    \"keyword3\": {\n" +
                "      \"value\": \"" + goodsName + "\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    },\n" +
                "    \"keyword4\": {\n" +
                "      \"value\": \"" + loadDate + "点发货\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    },\n" +
                "    \"remark\": {\n" +
                "      \"value\": \"" + mblno + "\",\n" +
                "      \"color\": \"#173177\"\n" +
                "    }\n" +
                "  }\n" +
                "}";
        try {
            // 客户端
            OkHttpClient client = new OkHttpClient();
            // 构建Request请求对象
            RequestBody body = RequestBody.create(MediaType.parse("application/xml;charset=utf-8"), jsonBody);
            Request request = new Request.Builder().url(templateMsgUrl + "?access_token=" + AccessTokenUtils.getToken()).post(body).build();
            // 请求接口，拿到token信息
            Response response = client.newCall(request).execute();
            // 判断成功与否
            if (response.isSuccessful()) {
                // 拿到相应结果
                String string = response.body().string();
                System.out.println("拿到结果了：" + string);
            }
        } catch (Exception e) {
        }
        return null;
    }

}
