package com.ruoyi.oauth.wx.service.Impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.auth.common.domain.OauthUser;
import com.ruoyi.auth.common.service.IOauthUserService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.UserDetailsServiceImpl;
import com.ruoyi.oauth.wx.constant.WxAppConstant;
import com.ruoyi.oauth.wx.domain.WxLoginUser;
import com.ruoyi.oauth.wx.service.WxLoginService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;

@Service
public class WxPubLoginServiceImpl implements WxLoginService {

    @Autowired
    private WxAppConstant wxH5Constant;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IOauthUserService oauthUserService;

    @Autowired
    private SysLoginService sysLoginService;

    @Override
    public String doLogin(String code, boolean autoRegister) {
        JSONObject doAuth = doAuth(
                wxH5Constant.getUrl(),
                wxH5Constant.getAppId(),
                wxH5Constant.getAppSecret(),
                code);
        String openid = doAuth.getString("openid");
        OauthUser selectOauthUser = oauthUserService.selectOauthUserByUUID(openid);
        SysUser sysUser = null;
        if (selectOauthUser == null) {
            if (autoRegister) {
                sysUser = new SysUser();
                sysUser.setUserName(openid);
                sysUser.setNickName(openid);
                sysUser.setPassword(SecurityUtils.encryptPassword(code));
                userService.registerUser(sysUser);
                OauthUser oauthUser = new OauthUser();
                oauthUser.setUserId(sysUser.getUserId());
                oauthUser.setOpenId(doAuth.getString("openid"));
                oauthUser.setUuid(doAuth.getString("openid"));
                oauthUser.setSource("WXMiniApp");
                oauthUser.setAccessToken(doAuth.getString("session_key"));
                oauthUserService.insertOauthUser(oauthUser);
            }
        } else {
            sysUser = userService.selectUserById(selectOauthUser.getUserId());
        }
        if (sysUser == null) {
            throw new ServiceException("该微信未绑定用户");
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS,
                MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) userDetailsServiceImpl.createLoginUser(sysUser);
        sysLoginService.recordLoginInfo(loginUser.getUserId());
        return tokenService.createToken(loginUser);
    }

    /**
     * 获取微信用户信息
     */
    private WxLoginUser getWechatUserInfo(String accessToken, String openid) {
        try {
            String url = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s",
                    accessToken, openid);

            RestTemplate restTemplate = new RestTemplate();
            String response = restTemplate.getForObject(url, String.class);
            JSONObject json = JSONObject.parseObject(response);

            if (json.containsKey("errcode")) {
                throw new ServiceException("获取微信用户信息失败: " + json.getString("errmsg"));
            }

            WxLoginUser userInfo = new WxLoginUser();
            userInfo.setOpenid(json.getString("openid"));
            userInfo.setNickname(json.getString("nickname"));
            userInfo.setProvince(json.getString("province"));
            userInfo.setCity(json.getString("city"));
            userInfo.setCountry(json.getString("country"));
            userInfo.setUnionid(json.getString("unionid"));

            return userInfo;
        } catch (Exception e) {
            throw new ServiceException("获取微信用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 验证微信token（可选）
     */
    private boolean validateWechatToken(String accessToken, String openid) {
        try {
            String url = String.format("https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s",
                    accessToken, openid);

            RestTemplate restTemplate = new RestTemplate();
            restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
            restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));

            String response = restTemplate.getForObject(url, String.class);
            JSONObject json = JSONObject.parseObject(response);

            return json.getInteger("errcode") == 0;
        } catch (Exception e) {
            // 如果验证失败，可以根据需求决定是否允许登录
            // 返回 true 表示跳过验证，返回 false 表示验证失败
            System.err.println("微信token验证失败: " + e.getMessage());
            return true; // 根据安全要求调整
        }
    }
    @Override
    public String doRegister(OauthUser oauthUser) {
        if (StringUtils.isEmpty(oauthUser.getCode())) {
            return "没有凭证";
        }
        if (oauthUser.getUserId() == null) {
            return "请先注册账号";
        }
        JSONObject doAuth = doAuth(
                wxH5Constant.getUrl(),
                wxH5Constant.getAppId(),
                wxH5Constant.getAppSecret(),
                oauthUser.getCode());
        oauthUser.setOpenId(doAuth.getString("openid"));
        oauthUser.setUuid(doAuth.getString("openid"));
        oauthUser.setSource("WXPub");
        oauthUser.setAccessToken(doAuth.getString("session_key"));
        oauthUserService.insertOauthUser(oauthUser);
        return "";
    }

    @Override
    public JSONObject doAuth(String url, String appid, String secret, String code) {
        return WxLoginService.super.doAuth(url, appid, secret, code);
    }

}
