package com.ruoyi.common.config;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * JiPushService
 *
 * @author ruoyi
 * @version 1.0.0
 * @since 2023年8月04日 09:36
 **/
@Component
public class JiPushService {
    private static Logger logger = LoggerFactory.getLogger(JiPushService.class);

    //正常app
    private static final String APP_KEY = "0c59b75aa582448dbc9b8c71";
    private static final String MASTER_SECRET = "a11f20252bc10bb79164b0c7";

    /**
     * 推送所有人
     * @param content 推送的内容
     * @param type 状态
     * @return
     */
    public static void allPush(String content,Integer type, String id) {
        JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = buildPushObject_all_registrationId_alert(content,type,id);
        try {
            PushResult result = jpushClient.sendPush(payload);
            logger.info("Got result - " + result);
        } catch (APIConnectionException e) {
            // Connection error, should retry later
            logger.error("Connection error, should retry later", e);
        } catch (APIRequestException e) {
            // Should review the error, and fix the request
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }finally {
            jpushClient.close();
        }
    }

    /**
     * 推送指定的人
     * @param list 指定的人
     * @param content 推送的内容
     * @param type 备用参数
     * @param id 备用参数
     * @return
     */
    public static void someonePush(List<String> list, String content, Integer type, String id) {
        JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = buildPushObject_someOne_registrationId_alert(list,content,type,id);
        try {
            PushResult result = jpushClient.sendPush(payload);
            logger.info("Got result - " + result);

        } catch (APIConnectionException e) {
            // Connection error, should retry later
            logger.error("Connection error, should retry later", e);

        } catch (APIRequestException e) {
            // Should review the error, and fix the request
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }finally {
            jpushClient.close();
        }
    }

    /**
     * 推送指定的人
     * @param list 指定的人
     * @param content 推送的内容
     * @param type 状态0
     * @return
     */
    public static void cabPush(List<String> list,String content,Integer type) {
        JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = custom_android_message(list,content,type);
        try {
            PushResult result = jpushClient.sendPush(payload);
            logger.info(",Got result - " + result);

        } catch (APIConnectionException e) {
            // Connection error, should retry later
            logger.error("Connection error, should retry later", e);

        } catch (APIRequestException e) {
            // Should review the error, and fix the request
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }finally {
            jpushClient.close();
        }
    }

    /**
     * 构建推送对象：所有平台，推送目标是所有人，通知内容为content。
     * @return
     */
    public static PushPayload buildPushObject_all_registrationId_alert(String content,Integer type, String id) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.all())
                .setNotification(Notification.newBuilder()    //ios
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .setBadge(0)
                                .addExtra("type", type)
                                .addExtra("id", id)
                                .build())
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setAlert(content)
                                .addExtra("type", type)
                                .addExtra("id", id)
                                .build())
                        .build())
                .setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(86400)
                        .build()
                )
                .build();
    }

    /**
     * 构建推送对象：所有平台，推送目标是指定的人，通知内容为 content。
     * @return
     */
    public static PushPayload buildPushObject_someOne_registrationId_alert(List<String> list, String content,Integer type,String id) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.alias(list))  //alias是别名   registrationId是设备标识
                .setNotification(Notification.newBuilder()    //ios
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .setBadge(0)
                                .addExtra("type", type)
                                .addExtra("id", id)
                                .build())
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setAlert(content)
                                .addExtra("type", type)
                                .addExtra("id", id)
                                .build())
                        .build())
                .setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(86400)
                        .build()
                )
                .build();
    }

    /**
     * 构建推送对象：android设备 柜子上的，推送目标是指定的人，通知内容为 content。
     * @return
     */
    public static PushPayload custom_android_message(List<String> list, String content,Integer type) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.registrationId(list))
                .setMessage(Message.newBuilder()
                        .setMsgContent(content)
                        .addExtra("type", type)
                        .build())
                .setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(86400)
                        .build()
                )
                .build();
    }


    /**
     * 构建推送对象：android设备 柜子上的，音频通话服务 推送目标是指定的人，通知内容为 content。
     * @return
     */
    public static PushPayload custom_android_call_message(List<String> list, String content,Integer type, String userId, String token) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.registrationId(list))
                .setMessage(Message.newBuilder()
                        .setMsgContent(content)
                        .addExtra("type", type)
                        .addExtra("userId", userId)
                        .addExtra("token", token)
                        .build())
                .setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(86400)
                        .build()
                )
                .build();
    }


    /**
     * 构建推送对象：android设备 柜子上的，音频通话服务 推送目标是指定的人，通知内容为 content。
     * @return
     */
    public static PushPayload custom_all_call_message(List<String> list, String content,Integer type) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.registrationId(list))
                .setMessage(Message.newBuilder()
                        .setMsgContent(content)
                        .addExtra("type", type)
                        .build())
                .setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(86400)
                        .build()
                )
                .build();
    }

}
