package com.usoftchina.qywx.sdk;

import com.usoftchina.qywx.sdk.config.Agent;
import com.usoftchina.qywx.sdk.config.QywxProperties;
import com.usoftchina.qywx.sdk.dto.*;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.ModelMap;

/**
 * 消息推送
 *
 * @author yingp
 */
public class MessageSdk extends BaseSdk {

    public MessageSdk(QywxProperties properties) {
        super(properties);
    }

    /**
     * 发送消息
     * 应用支持推送文本、图片、视频、文件、图文等类型
     *
     * @param agentCode 应用code
     * @param req
     */
    public SendMessageResp send(String agentCode, SendMessageReq req) {
        Agent agent = getAgentMap().get(agentCode);
        if (null == agent) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        req.agentId(agent.getId());
        ResponseEntity<SendMessageResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/message/send?access_token={access_token}",
                req.build(), SendMessageResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)));
        assertOK(resp);
        return resp.getBody();
    }

    /**
     * 更新任务卡片消息状态
     * 应用可以发送任务卡片消息，发送之后可再通过接口更新用户任务卡片消息的选择状态。
     *
     * @param agentCode 应用code
     * @param req
     * @return
     */
    public UpdateTaskCardResp updateTaskCard(String agentCode, UpdateTaskCardReq req) {
        Agent agent = getAgentMap().get(agentCode);
        if (null == agent) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        req.agentId(agent.getId());
        ResponseEntity<UpdateTaskCardResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/message/update_taskcard?access_token={access_token}",
                req.build(), UpdateTaskCardResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)));
        assertOK(resp);
        return resp.getBody();
    }

    /**
     * 创建群聊会话
     * 只允许企业自建应用调用，且应用的可见范围必须是根部门；
     * 群成员人数不可超过管理端配置的“群成员人数上限”，且最大不可超过500人；
     * 每企业创建群数不可超过1000/天；
     *
     * @param agentCode 应用code
     * @param req
     * @return 会话ID
     */
    public String createChat(String agentCode, CreateChatReq req) {
        if (!getAgentMap().containsKey(agentCode)) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        ResponseEntity<CreateChatResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/appchat/create?access_token={access_token}",
                req.build(), CreateChatResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)));
        assertOK(resp);
        return resp.getBody().getChatid();
    }

    /**
     * 修改群聊会话
     *
     * @param agentCode 应用code
     * @param req
     */
    public void updateChat(String agentCode, UpdateChatReq req) {
        if (!getAgentMap().containsKey(agentCode)) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        ResponseEntity<BaseResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/appchat/update?access_token={access_token}",
                req.build(), BaseResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)));
        assertOK(resp);
    }

    /**
     * 获取群聊会话
     *
     * @param agentCode 应用code
     * @param chatId    群聊id
     * @return
     */
    public GetChatResp.Chat getChat(String agentCode, String chatId) {
        if (!getAgentMap().containsKey(agentCode)) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        ResponseEntity<GetChatResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/appchat/get?access_token={access_token}&chatid={chatid}",
                GetChatResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)).addAttribute("chatid", chatId));
        assertOK(resp);
        return resp.getBody().getChat_info();
    }

    /**
     * 应用推送消息
     * 应用支持推送文本、图片、视频、文件、图文等类型。
     * <p>
     * 只允许企业自建应用调用，且应用的可见范围必须是根部门；
     * chatid所代表的群必须是该应用所创建；
     * 每企业消息发送量不可超过2万人次/分，不可超过20万人次/小时（若群有100人，每发一次消息算100人次）；
     * 每个成员在群中收到的应用消息不可超过200条/分，1万条/天，超过会被丢弃（接口不会报错）；
     * </p>
     *
     * @param agentCode 应用code
     * @param req
     */
    public void sendChat(String agentCode, SendChatReq req) {
        if (!getAgentMap().containsKey(agentCode)) {
            throw new RuntimeException("没有找到应用" + agentCode);
        }
        ResponseEntity<BaseResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/appchat/send?access_token={access_token}",
                req.build(), BaseResp.class,
                new ModelMap("access_token", getAccessToken(agentCode)));
        assertOK(resp);
    }
}
