package com.palmnest.application.core.util;

import java.util.*;

import cn.superdesk.libs.common.json.JsonUtils;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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.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.AndroidNotification.Builder;
import cn.jpush.api.push.model.notification.Notification;
import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;

import javax.mail.search.SearchTerm;












import com.turo.pushy.apns.ApnsClient;
import com.turo.pushy.apns.ApnsClientBuilder;
import com.turo.pushy.apns.PushNotificationResponse;
import com.turo.pushy.apns.util.ApnsPayloadBuilder;
import com.turo.pushy.apns.util.SimpleApnsPushNotification;
import com.turo.pushy.apns.util.TokenUtil;

import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 安卓推送消息utils类
 *
 * @author longmeizhen
 */
public class PushMessageUtils {

    private static Logger LOG = LoggerFactory.getLogger(PushMessageUtils.class);

    //极光凭证
    //尚美
//    protected static final String MASTER_SECRET = "9d0f363c3f092a2512cbe703";
//    protected static final String APPKEY="a1b85d3cac445c6ff02b8310";
    protected static final String MASTER_SECRET = "eae59fe5f73d1cdcccaece5d";
    protected static final String APPKEY = "e5444a13f32711c85c9fa13e";


    /**
     * 去重复
     * @param devices
     * @return
     */
    private static List<String> getOnly(List<String> devices) {
        Set set = new HashSet<String>();
        List<String> list = new ArrayList<>();
        for (String deviceNo :
                devices) {
            if (set.add(deviceNo)) {
                list.add(deviceNo);
            }
        }

        return list;
    }

    /**
     * @param deviceNos
     * @param content
     * @param extra    自定义值
     * @return
     * @throws Exception
     */
    public static String sendPushMessageByAndroidWithResult(List<String> deviceNos, String content, Map<String, String> extra) throws Exception {
        return sendPushMessageByAndroidWithResult(deviceNos, null, content, extra);
    }


    /**
     * @param devices
     * @param content
     * @param extra    自定义值
     * @return
     * @throws Exception
     */
    public static String sendPushMessageByAndroidWithResult(List<String> devices, String title, String content, Map<String, String> extra) throws Exception {
        //去重复
        List<String> deviceNos =getOnly(devices);

        LOG.info("sendPushMessageByAndroidWithResult=====");
        LOG.info("sendPushMessageByAndroidWithResult==deviceNos===" + deviceNos);
        LOG.info("sendPushMessageByAndroidWithResult==title===" + title);
        LOG.info("sendPushMessageByAndroidWithResult==content===" + content);
        LOG.info("sendPushMessageByAndroidWithResult==extra===" + extra);

        ClientConfig clientConfig = ClientConfig.getInstance();
        JPushClient jpushClient = null;
        try {
            jpushClient = new JPushClient(MASTER_SECRET, APPKEY, null, clientConfig);
        } catch (Exception e) {
            return "fail";
        }
        PushPayload payload = buildPushObject_all_alias_alert(deviceNos, title, content, extra);
        try {
            PushResult result = jpushClient.sendPush(payload);
            LOG.info("Got result - " + result);
            return "success";
        } catch (APIConnectionException e) {
            e.printStackTrace();
            LOG.error("Connection error. Should retry later. ", e);
            LOG.error("Sendno: " + payload.getSendno());
            LOG.error("安卓推送消息失败：" + e.getMessage());
            return "fail:" + e.getMessage();

        } catch (APIRequestException e) {
            e.printStackTrace();
            LOG.error("Error response from JPush server. Should review and fix it. ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
            LOG.error("Sendno: " + payload.getSendno());
            LOG.error("安卓推送消息失败：" + e.getMessage());
            return "fail:" + e.getMessage();

        }
    }

    public static PushPayload buildPushObject_all_alias_alert(List<String> device, String title, String content, Map<String, String> extra) {
        //去重复
        List<String> deviceNos =getOnly(device);

        Builder builder = AndroidNotification.newBuilder().setAlert(content);
        if (title != null && !title.equals("")) {
            builder.setTitle(title);
        }
        if (extra != null && !extra.isEmpty()) {
            for (String key : extra.keySet()) {
                builder.addExtra(key, extra.get(key));
            }
        }
        Notification notification = Notification.newBuilder()
                .addPlatformNotification(builder.build()).build();
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.registrationId(deviceNos))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(false).setTimeToLive(86000).build())
                .build();
    }


    /**
     * @param deviceNo
     * @param content
     * @param map      自定义字典
     * @return
     * @throws Exception
     */
    public static String sendPushMessageByIosWithResult(List<String> deviceNo, String content, Map<String, String> map) throws Exception {
        return sendPushMessageByIosWithResult(deviceNo, null, content, map);
    }

    /**
     * @param devices
     * @param content
     * @param map      自定义字典
     * @return
     * @throws Exception
     */
    public static String sendPushMessageByIosWithResult(List<String> devices, String title, String content, Map<String, String> map, String url) throws Exception {
//		 String deviceToken = "2657ebf51441cf49d4fb808fc328e79f982b49f4c8118efe4093046ad9b50bbf";  
//	        String alert = "给你发信息了";//push的内容  
        //去重复
        List<String> deviceNos =getOnly(devices);


        int badge = 0;//图标小红圈的数值
        String sound = "default";//铃音

        List<String> tokens = new ArrayList<String>();
        tokens.addAll(deviceNos);
        String certificatePath = PushMessageUtils.class.getClassLoader().getResource("/floorWindow.p12").getPath();
//		 String certificatePath = PushMessageUtils.class.getClassLoader().getResource("./pushCertificate/证书.p12").getPath();

//		 String certificatePassword = "Huang0831";//此处注意导出的证书密码不能为空因为空密码会报错   广州掌巢公众号密码
//		 String certificatePassword = "Huang0905";//UAT环境
        String certificatePassword = "Huang0910";//上架正式环境
        boolean sendCount = false;

        try {
            PushNotificationPayload payLoad = PushNotificationPayload.complex();
            if (title != null && !title.equals("")) {
                //"{\r\n" +
                // "  \"aps\" : {\r\n" +
                // "    \"alert\" : {\r\n" +
                // "      \"title\" : \"11111\",\r\n" +
                // "      \"body\" : \"Your message Here\"\r\n" +
                // "    },\r\n" +
                // "    \"sound\" : \"default\",\r\n" +
                // "    \"badge\" : 222\r\n" +
                // "  }\r\n" +
                // "}\r\n" +
                // ""
                String json1 = "{\"aps\":{\"alert\":{\"title\":\"" + title + "\",\"body\":\"" + content + "\"},\"url\":\"" + url + "\"}}";
                payLoad = PushNotificationPayload.fromJSON(json1);
            } else {
                payLoad.addAlert(content); // 消息内容
            }

            payLoad.addBadge(badge); // iphone应用图标上小红圈上的数值
            if (!StringUtils.isBlank(sound)) {
                payLoad.addSound(sound);//铃音
            }

            if (map != null && !map.isEmpty()) {
                Object[] keys = map.keySet().toArray();
                Object[] vals = map.values().toArray();
                if (keys != null && vals != null && keys.length == vals.length) {
                    for (int i = 0; i < map.size(); i++) {
                        payLoad.addCustomDictionary(String.valueOf(keys[i]), String.valueOf(vals[i]));
                    }
                }
            }
            PushNotificationManager pushManager = new PushNotificationManager();
            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务
            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, true));
            List<PushedNotification> notifications = new ArrayList<PushedNotification>();
            // 发送push消息
            if (sendCount) {
                Device device = new BasicDevice();
                device.setToken(tokens.get(0));
                PushedNotification notification = pushManager.sendNotification(device, payLoad, true);
                notifications.add(notification);
            } else {
                List<Device> device = new ArrayList<Device>();
                for (String token : tokens) {
                    device.add(new BasicDevice(token));
                }
                notifications = pushManager.sendNotifications(payLoad, device);
            }
            pushManager.stopConnection();
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("IOS推送消息发送失败：" + e.getMessage());
            return "fail:" + e.getMessage();
        }
    }

//    public static void main(String[] args) {
//        List<String> s =Arrays.asList("a8e52b1d89a508be64e9a5ae8de77bda0852728ea022b47a356e9f2b0900f4b7","a8e52b1d89a508be64e9a5ae8de77bda0852728ea022b47a356e9f2b0900f4b7","a8e52b1d89a508be64e9a5ae8de77bda0852728ea022b47a356e9f2b0900f4b8","a8e52b1d89a508be64e9a5ae8de77bda0852728ea022b47a356e9f2b0900f4b7");
//        Set set = new HashSet<String>();
//        List<String> deviceNo = new ArrayList<>();
//        for (String d :
//                s) {
//            if (set.add(d)) {
//                deviceNo.add(d);
//            }
//        }
//
//        System.out.println(JsonUtils.toJson(deviceNo));
//    }
    /**
     * @param devices
     * @param content
     * @param map      自定义字典
     * @return
     * @throws Exception
     */
    public static String sendPushMessageByIosWithResult(List<String> devices, String title, String content, Map<String, String> map) throws Exception {
        List<String> deviceNos =getOnly(devices);

        LOG.info("sendPushMessageByIosWithResult=====");
        LOG.info("sendPushMessageByIosWithResult==deviceNo===" + deviceNos);
        LOG.info("sendPushMessageByIosWithResult==title===" + title);
        LOG.info("sendPushMessageByIosWithResult==content===" + content);
        LOG.info("sendPushMessageByIosWithResult==map===" + map.toString());


//		 String deviceToken = "2657ebf51441cf49d4fb808fc328e79f982b49f4c8118efe4093046ad9b50bbf";  
//	        String alert = "给你发信息了";//push的内容  
        int badge = 0;//图标小红圈的数值
        String sound = "default";//铃音

        List<String> tokens = new ArrayList<String>();
        tokens.addAll(deviceNos);
//        String certificatePath = PushMessageUtils.class.getClassLoader().getResource("/floorWindow.p12").getPath();
//		 String certificatePath = PushMessageUtils.class.getClassLoader().getResource("./pushCertificate/证书.p12").getPath();
        String certificatePath = "C:/Users/Administrator/Desktop/floorWindow.p12";
        //String certificatePassword = "Huang0831";//此处注意导出的证书密码不能为空因为空密码会报错   广州掌巢公众号密码
//		 String certificatePassword = "Huang0905";//UAT环境
        String certificatePassword = "Huang0910";//正式上架密码
        boolean sendCount = false;

        try {
            PushNotificationPayload payLoad = PushNotificationPayload.complex();
            if (title != null && !title.equals("")) {
                //"{\r\n" +
                // "  \"aps\" : {\r\n" +
                // "    \"alert\" : {\r\n" +
                // "      \"title\" : \"11111\",\r\n" +
                // "      \"body\" : \"Your message Here\"\r\n" +
                // "    },\r\n" +
                // "    \"sound\" : \"default\",\r\n" +
                // "    \"badge\" : 222\r\n" +
                // "  }\r\n" +
                // "}\r\n" +
                // ""
                String json1 = "{\"aps\":{\"alert\":{\"title\":\"" + title + "\",\"body\":\"" + content + "\"}}}";
                payLoad = PushNotificationPayload.fromJSON(json1);
            } else {
                payLoad.addAlert(content); // 消息内容
            }

            payLoad.addBadge(badge); // iphone应用图标上小红圈上的数值
            if (!StringUtils.isBlank(sound)) {
                payLoad.addSound(sound);//铃音
            }

            if (map != null && !map.isEmpty()) {
                Object[] keys = map.keySet().toArray();
                Object[] vals = map.values().toArray();
                if (keys != null && vals != null && keys.length == vals.length) {
                    for (int i = 0; i < map.size(); i++) {
                        payLoad.addCustomDictionary(String.valueOf(keys[i]), String.valueOf(vals[i]));
                    }
                }
            }
            PushNotificationManager pushManager = new PushNotificationManager();
            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务
            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, true));
            List<PushedNotification> notifications = new ArrayList<PushedNotification>();
            // 发送push消息
            if (sendCount) {
                Device device = new BasicDevice();
                device.setToken(tokens.get(0));
                PushedNotification notification = pushManager.sendNotification(device, payLoad, true);
                notifications.add(notification);
            } else {
                List<Device> device = new ArrayList<Device>();
                for (String token : tokens) {
                    device.add(new BasicDevice(token));
                }
                notifications = pushManager.sendNotifications(payLoad, device);
            }
            pushManager.stopConnection();
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("IOS推送消息发送失败：" + e.getMessage());
            return "fail:" + e.getMessage();
        }
    }
    
    
    
    
    
    
    
    
    
    private static ApnsClient apnsClient = null;
    private static final Semaphore semaphore = new Semaphore(10000);
    
    public static void pushIosMsg(String deviceNo,String alertTitle, String alertBody){
    	List<String> deviceTokens =new ArrayList<String>();
    	deviceTokens.add(deviceNo);
    	Map<String,String> map=new HashMap<String,String>();
    	push(deviceTokens, alertTitle, alertBody,map);
    }

    public static void push(final List<String> deviceTokens, String alertTitle, String alertBody, Map<String, String> map) {
        if(apnsClient == null) {
            try{
                EventLoopGroup eventLoopGroup = new NioEventLoopGroup(4);
                
//                String certificatePath = PushMessageUtils.class.getClassLoader().getResource("/floorWindow.p12").getPath();//linux目录下获取证书地址
                String certificatePath ="D:\\test\\floorWindow.p12";//本地地址
                String certificatePassword = "Huang0910";//此处注意导出的证书密码不能为空因为空密码会报错
//                apnsClient = new ApnsClientBuilder().setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST).setClientCredentials(new File(certificatePath), certificatePassword)
//                        .setConcurrentConnections(4).setEventLoopGroup(eventLoopGroup).build();//正式环境
              apnsClient = new ApnsClientBuilder().setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST).setClientCredentials(new File(certificatePath), certificatePassword)
              .setConcurrentConnections(4).setEventLoopGroup(eventLoopGroup).build();//测试环境
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        
        final CountDownLatch latch = new CountDownLatch(deviceTokens.size());
        try{
            final AtomicLong successCnt = new AtomicLong(0);
            for(String deviceToken : deviceTokens) {
//                ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
                String sound="tips_addOrder.mp3";
//                payloadBuilder.setAlertBody("{\"title\":\"" + alertTitle + "\",\"body\":\"" + alertBody + "\",\"mediaFileCode\":\"" + sound + "\",\"tipsNum\":\"" + 123 + "\"}," +
//                        "\"url\":\"" + "http://www.baidu.com" + "\"}");
//                payloadBuilder.setAlertTitle(alertTitle);
//                payloadBuilder.setAlertSubtitle("dfsaf");//副标题
//                String sound="tips_addOrder.mp3";
                String json = "{\"tipsNum\":\"123\",\"mediaPushTitle\":\"我是标题哦\",\"code\":\"5001\",\"mediaFileCode\":\"tips_addOrder\",\"aps\":{\"alert\":{\"subtitle\":\"dfsaf\",\"body\":\"我的内容\",\"title\":\"我的标题\"},\"sound\":\"tips_addOrder.mp3\",\"url\":\"http://zhly.superdesk.cn/avicfile/super_wechat/noticeDetail/index.html?type=APP_NIOTICE_AUDIT&id=784\"},\"mediaPushContent\":\"我是内容哦\",\"id\":\"6E6BEE3BBF91766A\",\"mediaFileUrl\":\"https://superdesk.avic-s.com/avicfile/tips/tips_addOrder.mp3\"}";
//                
//                if (map != null && !map.isEmpty()) {
//                    Object[] keys = map.keySet().toArray();
//                    Object[] vals = map.values().toArray();
//                    if (keys != null && vals != null && keys.length == vals.length) {
//                        for (int i = 0; i < map.size(); i++) {
//                        	payloadBuilder.addCustomProperty(String.valueOf(keys[i]), String.valueOf(vals[i]));
//                        }
//                    }
//                }
//                payloadBuilder.setSoundFileName(sound);
//                String payload = payloadBuilder.buildMdmPayload(json);
//                String payload = payloadBuilder.buildWithDefaultMaximumLength();
//                LOG.info("payload:"+payload);
                final String token = TokenUtil.sanitizeTokenString(deviceToken);
                SimpleApnsPushNotification pushNotification = new SimpleApnsPushNotification(token, "com.ChaoJiQianTai.ZHLY", json);
                try{
                    semaphore.acquire();
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
                final Future future = apnsClient.sendNotification(pushNotification);
                future.addListener(new GenericFutureListener() {
                    @Override
                    public void operationComplete(Future pushNotificationResponseFuture) throws Exception {
                        if(future.isSuccess()) {
                            final PushNotificationResponse response = (PushNotificationResponse)future.getNow();
                            if(response.isAccepted()) {
                                successCnt.incrementAndGet();
                            } else{
                                Date invalidTime = response.getTokenInvalidationTimestamp();
                                if(invalidTime != null) {
                                }
                            }
                        } else{
                        }
                        latch.countDown();
                        semaphore.release();
                    }
                });
            }
        }catch(Exception e){
        	e.printStackTrace();
        }
        
        try{
            latch.await(20, TimeUnit.SECONDS);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception
    {
    	
        String [] arr={"123","456"};
        System.out.println(StringUtils.join(arr, ","));
//        String deviceToken = "b0f1ccfebe6c36cb39b515a4931aa92b3d6da865448a3f20aea3bda3f3a12336";
//        
//        List<String> tokens = new ArrayList<String>();
//        tokens.add(deviceToken);
////        tokens.add("53c46dce07e13396d078579b9032f02db0f02384de5b0376a69b51bceaf6ff9f");
//        PushMessageUtils testPush=new PushMessageUtils();
//        Map<String,String> map=new HashMap<String,String>();
//        map.put("id", "100");
//        map.put("code", "200");
//        map.put("url", "https://fanyi.baidu.com/?aldtype=16047#auto/zh");
//        map.put("mediaFileCode", "tips_addOrder");
//        map.put("mediaFileUrl", "https://superdesk.avic-s.com/avicfile/tips/tips_addOrder.mp3");
//        map.put("mediaPushTitle", "我是标题哦");
//        map.put("mediaPushContent", "我是内容哦");
//        map.put("tipsNum", "123");
//        testPush.push(tokens,"我的标题","我的内容",map);
//        String deviceToken = "23b7e30356a46f8253831446d46dbe7f511815e6a6a8d584ae7b2d76f44b62c4";
//        String alert = "给你发信息了";//push的内容
//        int badge = 3;//图标小红圈的数值
//        String sound = "default";//铃音
//
//        List<String> tokens = new ArrayList<String>();
//        tokens.add(deviceToken);
//        String certificatePath = "D:/floorWindow.p12";
//        String certificatePassword = "Huang0910";//此处注意导出的证书密码不能为空因为空密码会报错
//        boolean sendCount = true;
//
//        try
//        {
//            PushNotificationPayload payLoad = new PushNotificationPayload();
//            payLoad.addAlert(alert); // 消息内容
//            payLoad.addBadge(badge); // iphone应用图标上小红圈上的数值
//
//            if (!StringUtils.isBlank(sound))
//            {
//                payLoad.addSound(sound);//铃音
//            }
//            PushNotificationManager pushManager = new PushNotificationManager();
//            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务
//            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, true));
//            List<PushedNotification> notifications = new ArrayList<PushedNotification>();
//            // 发送push消息
//            if (sendCount)
//            {
//                Device device = new BasicDevice();
//                device.setToken(tokens.get(0));
//                PushedNotification notification = pushManager.sendNotification(device, payLoad, true);
//                notifications.add(notification);
//            }
//            else
//            {
//                List<Device> device = new ArrayList<Device>();
//                for (String token : tokens)
//                {
//                    device.add(new BasicDevice(token));
//                }
//                notifications = pushManager.sendNotifications(payLoad, device);
//            }
//            pushManager.stopConnection();
//        }
//        catch (Exception e)
//        {
//            e.printStackTrace();
//        }
    }

}
