package com.ruoyi.app.utils.im;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.vo.ImAccountVo;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * IM 平台 HTTP 客户端。
 *
 * <p>封装 IM 平台「创建用户」接口（extCreate）：
 * POST {base-url}{create-path}，请求头带 extToken，返回 apiKey + userId。
 *
 * <p>仿 {@code com.ruoyi.app.utils.newebpay.NewebPay} 结构，使用 org.apache.http；
 * 配置经 @Value 从 application.yml 的 im 段注入（域名/令牌均不硬编码）。
 *
 * @author ruoyi
 * @date 2026-06-23
 */
@Component
public class ImClient {

    @Value("${im.base-url}")
    private String baseUrl;

    @Value("${im.ext-token}")
    private String extToken;

    @Value("${im.create-path}")
    private String createPath;

    @Value("${im.timeout-ms}")
    private int timeoutMs;

    /**
     * 调用 IM 平台 extCreate 创建用户，返回凭证。
     *
     * <p>请求体 JSON：{@code {"nickName": <昵称>, "type": 0}}，请求头带 extToken。
     *
     * @param nickName 昵称（由上层取 userName，无则取 phone）
     * @return 含 apiKey、imUserId(String) 的凭证对象
     * @throws ServiceException IM 平台返回失败、超时或网络异常时抛出（由上层捕获，不写库）
     */
    public ImAccountVo createAccount(String nickName) {
        String url = baseUrl + createPath;
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(timeoutMs)
                .setSocketTimeout(timeoutMs)
                .build();
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);
        post.setHeader("extToken", extToken);
        post.setHeader("Content-Type", "application/json");
        // 请求体：nickName + type(默认 0)
        JSONObject reqBody = new JSONObject();
        reqBody.put("nickName", nickName);
        reqBody.put("type", 0);
        post.setEntity(new StringEntity(reqBody.toJSONString(), StandardCharsets.UTF_8));

        String body;
        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse res = client.execute(post)) {
            body = EntityUtils.toString(res.getEntity(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new ServiceException("IM 账号创建失败：网络异常 " + e.getMessage());
        }

        JSONObject resp = JSON.parseObject(body);
        Integer code = resp.getInteger("code");
        if (code == null || code != 200) {
            throw new ServiceException("IM 账号创建失败：" + resp.getString("message"));
        }
        JSONObject data = resp.getJSONObject("data");
        if (data == null) {
            throw new ServiceException("IM 账号创建失败：响应缺少 data");
        }
        String apiKey = data.getString("apiKey");
        Long userId = data.getLong("userId");
        if (apiKey == null || apiKey.isEmpty() || userId == null) {
            throw new ServiceException("IM 账号创建失败：凭证字段缺失");
        }

        ImAccountVo vo = new ImAccountVo();
        vo.setImApiKey(apiKey);
        vo.setImUserId(String.valueOf(userId)); // String 规避前端 Long 精度丢失
        return vo;
    }
}
