package com.cnd3b.utility.qywechat.base;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
public class SendMsg {

    private String address = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
    private URLConnection connection;
    private OutputStreamWriter out;
    private URL url;

    public SendMsg() throws IOException {
        try {
            address = address + GetAccessToken.get();
            url = new URL(address);
            connection = url.openConnection();
            connection.setDoOutput(true);
            connection.setConnectTimeout(500);
            out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 向用户发送文字消息
     *
     * @param tousers  成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid    企业应用的id，整型。可在应用的设置页面查看
     * @param save     表示是否是保密消息，0表示否，1表示是，默认0
     * @param content  消息内容
     * @return 返回发送信息的结果是否成功
     * @throws IOException
     */
    public String TextMsg(String[] tousers, String[] topartys, String appid, String save, String content)
            throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "text");
        object.put("agentid", appid);
        JSONObject textobject = new JSONObject();
        textobject.put("content", content);
        object.put("text", textobject);
        object.put("safe", save);
        return Send(object);
    }

    /**
     * @param tousers  成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid    企业应用的id，整型。可在应用的设置页面查看
     * @param save     表示是否是保密消息，0表示否，1表示是，默认0
     * @param MEDIA_ID 图片媒体文件id，可以调用上传临时素材或者永久素材接口获取,永久素材media_id必须由发消息的应用创建
     * @return 返回发送信息的结果是否成功
     * @throws IOException
     */
    public String ImageMsg(String[] tousers, String[] topartys, String appid, String save, String MEDIA_ID)
            throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "image");
        object.put("agentid", appid);
        JSONObject textobject = new JSONObject();
        textobject.put("media_id", MEDIA_ID);
        object.put("image", textobject);
        object.put("safe", save);
        return Send(object);
    }

    /**
     * @param tousers  成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid    企业应用的id，整型。可在应用的设置页面查看
     * @param save     表示是否是保密消息，0表示否，1表示是，默认0
     * @param MEDIA_ID 图片媒体文件id，可以调用上传临时素材或者永久素材接口获取,永久素材media_id必须由发消息的应用创建
     * @return 返回发送信息的结果是否成功
     * @throws IOException
     */
    public String VoiceMsg(String[] tousers, String[] topartys, String appid, String save, String MEDIA_ID)
            throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "voice");
        object.put("agentid", appid);
        JSONObject textobject = new JSONObject();
        textobject.put("media_id", MEDIA_ID);
        object.put("voice", textobject);
        object.put("safe", save);
        return Send(object);
    }

    /**
     * @param tousers     成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys    部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid       企业应用的id，整型。可在应用的设置页面查看
     * @param save        表示是否是保密消息，0表示否，1表示是，默认0
     * @param MEDIA_ID    图片媒体文件id，可以调用上传临时素材或者永久素材接口获取,永久素材media_id必须由发消息的应用创建
     * @param Title       视频消息的标题
     * @param Description 视频消息的描述
     * @return 返回发送信息的结果是否成功
     * @throws IOException
     */
    public String VideoMsg(String[] tousers, String[] topartys, String appid, String save, String MEDIA_ID,
                           String Title, String Description) throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "video");
        object.put("agentid", appid);
        JSONObject textobject = new JSONObject();
        textobject.put("media_id", MEDIA_ID);
        textobject.put("title", Title);
        textobject.put("description", Description);
        object.put("video", textobject);
        object.put("safe", save);
        return Send(object);
    }

    /**
     * @param tousers  成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid    企业应用的id，整型。可在应用的设置页面查看
     * @param save     表示是否是保密消息，0表示否，1表示是，默认0
     * @param MEDIA_ID 图片媒体文件id，可以调用上传临时素材或者永久素材接口获取,永久素材media_id必须由发消息的应用创建
     * @return 返回发送信息的结果是否成功
     * @throws IOException
     */
    public String fileMsg(String[] tousers, String[] topartys, String appid, String save, String MEDIA_ID)
            throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "file");
        object.put("agentid", appid);
        JSONObject textobject = new JSONObject();
        textobject.put("media_id", MEDIA_ID);
        object.put("file", textobject);
        object.put("safe", save);
        return Send(object);
    }

    /**
     * @param tousers  成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all， 则向关注该企业应用的全部成员发送
     * @param topartys 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     * @param appid    企业应用的id，整型。可在应用的设置页面查看
     * @param news     新闻列表 类型为List<Map<String, String>>，其中map中的KEY为
     *                 title，description，url，picurl。 title：标题 description：描述
     *                 url：点击后跳转的链接。 picurl：图文消息的图片链接，支持JPG、PNG格式，较好的效果为大图640*320，小图80
     *                 *80。如不填，在客户端不显示图片
     * @return
     * @throws IOException
     */
    public String NewsMsg(String[] tousers, String[] topartys, String appid, List<Map<String, String>> news)
            throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "news");
        object.put("agentid", appid);
        JSONObject newsobject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        for (Map<String, String> map : news) {
            JSONObject newobject = new JSONObject();
            newobject.put("title", map.get("title"));
            newobject.put("description", map.get("description"));
            newobject.put("url", map.get("url"));
            newobject.put("picurl", map.get("picurl"));
            jsonArray.add(newobject);
        }
        newsobject.put("articles", jsonArray);
        object.put("news", newsobject);
        return Send(object);
    }

    public String NewsMsg(String[] tousers, String[] topartys, String appid, JSONObject news) throws IOException {
        JSONObject object = new JSONObject();
        object.put("touser", join(tousers));
        object.put("toparty", join(topartys));
        object.put("totag", null);
        object.put("msgtype", "news");
        object.put("agentid", appid);
        object.put("news", news);
        return Send(object);
    }

    private String Send(JSONObject object) throws IOException {
        out.write(object.toString()); // 这里组织提交信息
        out.flush();
        out.close();
        // 获取返回数据
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line = null;
        StringBuffer content = new StringBuffer();
        while ((line = in.readLine()) != null) {
            // line为返回值，这就可以判断是否成功、
            content.append(line);
        }
        in.close();
        return content.toString();
    }

    /**
     * 将数值转化成字符串
     *
     * @param a
     * @return
     */
    public String join(String[] a) {
        StringBuilder b = null;
        if (a == null) {
            return b.toString();
        }
        for (String c : a) {
            if (b == null || b.toString().equals("")) {
                b = new StringBuilder(c);
            } else {
                b.append("|").append(c);
            }
        }
        return b.toString();
    }
}
