package com.ruoyi.app.service;

import com.ruoyi.app.utils.im.ImClient;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.InfoUser;
import com.ruoyi.system.domain.vo.ImAccountVo;
import com.ruoyi.system.service.IInfoUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * IM 账号开通服务（编排层）。
 *
 * <p>幂等校验 → 调用 IM 平台创建 → 回写用户表凭证。
 * 放在 ruoyi-admin 模块：同时依赖 {@link ImClient}（外部 HTTP，仿 NewebPay，
 * httpclient4 + fastjson2）与 {@link IInfoUserService}（用户表读写），
 * 避开 ruoyi-system 反向依赖 ruoyi-admin 的模块边界问题。
 *
 * @author ruoyi
 * @date 2026-06-23
 */
@Component
public class ImAccountService {

    @Autowired
    private ImClient imClient;

    @Autowired
    private IInfoUserService infoUserService;

    /**
     * 开通（或获取）当前用户的 IM 账号凭证。
     * 幂等：用户已有 IM 凭证时直接返回，不再调用 IM 平台。
     *
     * @param userId 用户ID
     * @return IM 凭证（apiKey + imUserId）
     */
    public ImAccountVo openImAccount(Long userId) {
        InfoUser user = infoUserService.getById(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        // 幂等：已有 IM 凭证直接返回，不再调用 IM 平台创建
        if (user.getImApiKey() != null && !user.getImApiKey().isEmpty()) {
            ImAccountVo exist = new ImAccountVo();
            exist.setImApiKey(user.getImApiKey());
            exist.setImUserId(user.getImUserId() == null ? null : String.valueOf(user.getImUserId()));
            return exist;
        }
        // 首次开通：nickName 取 userName，无则取 phone（哪个有值用哪个）
        String nickName = (user.getUserName() != null && !user.getUserName().isEmpty())
                ? user.getUserName() : user.getPhone();
        if (nickName == null || nickName.isEmpty()) {
            throw new ServiceException("用户昵称为空，无法创建 IM 账号");
        }
        ImAccountVo vo = imClient.createAccount(nickName);
        InfoUser update = new InfoUser();
        update.setUserId(userId);
        update.setImApiKey(vo.getImApiKey());
        update.setImUserId(Long.valueOf(vo.getImUserId()));
        infoUserService.updateById(update);
        return vo;
    }
}
