package com.ruoyi.database.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.database.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WechatPhoneService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;

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

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

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

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

    /**
     * 获取微信访问令牌
     */
    public String getAccessToken() {
        try {
            String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s",
                    accessTokenUrl, appId, appSecret);

            log.info("请求微信access_token, URL: {}", url);

            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            String responseBody = response.getBody();

            log.info("微信access_token响应: {}", responseBody);

            // 解析响应
            Map<String, Object> result = objectMapper.readValue(responseBody, Map.class);
            String accessToken = (String) result.get("access_token");
            Integer errcode = (Integer) result.get("errcode");

            if (accessToken != null) {
                log.info("成功获取微信access_token");
                return accessToken;
            } else if (errcode != null) {
                String errmsg = (String) result.get("errmsg");
                log.error("获取微信access_token失败: {} - {}", errcode, errmsg);
                throw new BusinessException("WECHAT_ACCESS_TOKEN_ERROR",
                        String.format("获取微信访问令牌失败[%s]: %s", errcode, errmsg));
            } else {
                throw new BusinessException("WECHAT_ACCESS_TOKEN_ERROR", "获取微信访问令牌失败: 响应格式错误");
            }

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取微信access_token异常", e);
            throw new BusinessException("WECHAT_ACCESS_TOKEN_ERROR", "获取微信访问令牌异常: " + e.getMessage());
        }
    }

    /**
     * 通过code获取用户手机号
     */
    public String getPhoneNumber(String code) {
        try {
            // 1. 获取access_token
            String accessToken = getAccessToken();

            // 2. 构建请求参数
            Map<String, String> requestBody = new HashMap<>();
            requestBody.put("code", code);

            String url = getPhoneNumberUrl + "?access_token=" + accessToken;

            log.info("请求微信手机号接口, URL: {}", url);
            log.debug("请求参数: code={}", code);

            // 3. 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);

            // 4. 调用微信接口
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
            String responseBody = response.getBody();

            log.info("微信手机号接口响应: {}", responseBody);

            // 5. 解析响应
            Map<String, Object> result = objectMapper.readValue(responseBody, Map.class);
            Integer errcode = (Integer) result.get("errcode");
            String errmsg = (String) result.get("errmsg");

            if (errcode != null && errcode != 0) {
                log.error("获取微信手机号失败: {} - {}", errcode, errmsg);
                throw new BusinessException("WECHAT_PHONE_ERROR",
                        String.format("获取手机号失败[%s]: %s", errcode, errmsg));
            }

            // 6. 提取手机号信息
            Map<String, Object> phoneInfo = (Map<String, Object>) result.get("phone_info");
            if (phoneInfo == null) {
                throw new BusinessException("WECHAT_PHONE_ERROR", "获取手机号失败: 响应中缺少phone_info");
            }

            String phoneNumber = (String) phoneInfo.get("phoneNumber");
            if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
                throw new BusinessException("WECHAT_PHONE_ERROR", "获取手机号失败: 手机号为空");
            }

            // 7. 验证手机号格式
            if (!validatePhoneNumber(phoneNumber)) {
                log.warn("获取到的手机号格式可能不正确: {}", phoneNumber);
                // 这里可以根据业务需求决定是否抛出异常
            }

            log.info("成功获取用户手机号: {}", phoneNumber);
            return phoneNumber;

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取微信手机号异常", e);
            throw new BusinessException("WECHAT_PHONE_ERROR", "获取微信手机号异常: " + e.getMessage());
        }
    }

    /**
     * 验证手机号格式
     */
    public boolean validatePhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
            return false;
        }
        // 简单的手机号格式验证
        return phoneNumber.matches("^1[3-9]\\d{9}$");
    }

    /**
     * 获取微信用户openid (如果需要)
     */
    public String getOpenId(String jsCode) {
        try {
            String url = String.format(
                    "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                    appId, appSecret, jsCode
            );

            log.info("请求微信openid, URL: {}", url.replace(jsCode, "***"));

            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            String responseBody = response.getBody();

            log.info("微信openid响应: {}", responseBody);

            Map<String, Object> result = objectMapper.readValue(responseBody, Map.class);
            String openid = (String) result.get("openid");
            Integer errcode = (Integer) result.get("errcode");

            if (openid != null) {
                log.info("成功获取微信openid");
                return openid;
            } else if (errcode != null) {
                String errmsg = (String) result.get("errmsg");
                throw new BusinessException("WECHAT_OPENID_ERROR",
                        String.format("获取openid失败[%s]: %s", errcode, errmsg));
            } else {
                throw new BusinessException("WECHAT_OPENID_ERROR", "获取openid失败: 响应格式错误");
            }

        } catch (Exception e) {
            log.error("获取微信openid异常", e);
            throw new BusinessException("WECHAT_OPENID_ERROR", "获取微信openid异常: " + e.getMessage());
        }
    }
}
