package com.wecloud.im.ws.sender;

import cn.hutool.core.codec.Base64;
import com.turo.pushy.apns.DeliveryPriority;
import com.turo.pushy.apns.PushType;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImIosApns;
import com.wecloud.im.push.PushUtils;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImIosApnsService;
import com.wecloud.im.ws.model.request.PushModel;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 异步系统推送
 */
@Component
@Slf4j
public class PushTask {

    @Autowired
    private ImIosApnsService imIosApnsService;


    @Autowired
    private ImInboxService imInboxService;

    /**
     * 谷歌推送地址
     */
    private static final String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";

    /**
     * 您收到一条新消息
     */
    private static final String PUSH_TITLE = "You have received a new message";

    /**
     * 点击查看
     */
    private static final String PUSH_BODY = "Click to view";

    private static final String title = "title";
    private static final String subTitle = "subTitle";

    /**
     * 异步系统推送
     *
     * @param imClientReceiver
     */
    @Async
    public void push(HashMap<String, String> pushMap, ImClient imClientReceiver, ImApplication imApplication) {
        log.info("push:" + imClientReceiver.getClientId());

        PushModel pushModel = new PushModel();

        if (pushMap == null || pushMap.isEmpty()) {
            pushModel.setTitle(PUSH_TITLE);
            pushModel.setSubTitle(PUSH_BODY);
        } else {
            pushModel.setTitle(pushMap.get(title));
            pushModel.setSubTitle(pushMap.get(subTitle));
        }

        // 校验参数
        if (imClientReceiver.getValid() == null || imClientReceiver.getDeviceToken() == null || imClientReceiver.getDeviceType() == null) {

            log.info("push参数错误");
            return;
        }
        // 设备不想收到推送提醒, 1想, 0不想
        if (imClientReceiver.getValid() == 0) {
            return;
        }

        //  设备类型1:ios; 2:android
        if (imClientReceiver.getDeviceType() == 1) {
            ios(pushModel, imClientReceiver, imApplication);

        } else {
            android(pushModel, imClientReceiver, imApplication);
        }
    }

    private void android(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
        // 安卓推送通道,友盟:1;firebase:2; 信鸽3
        if (imApplication.getAndroidPushChannel() == 1) {
            log.info("友盟");

            // 友盟推送
            PushUtils pushUtils = new PushUtils(imApplication.getUmengKey(), imApplication.getUmengSecret());

            // 安卓 单推
            String deviceTokenIOS = imClientReceiver.getDeviceToken();
            try {
                pushUtils.sendIOSUnicast(deviceTokenIOS, pushModel.getTitle(), pushModel.getSubTitle(), PUSH_BODY);
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else if (imApplication.getAndroidPushChannel() == 2) {

            //firebase:2
            log.info("android_firebase");

            firebase(pushModel, imClientReceiver, imApplication);

        } else if (imApplication.getAndroidPushChannel() == 3) {
            //  信鸽3
            log.info("信鸽3");


        } else {
            log.info("没有找到推送类型");
        }
    }

    private void ios(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
        // ios推送通道,友盟:1;firebase:2; apns原生:3
        if (imApplication.getIosPushChannel() == 1) {
            log.info("友盟");

            // 友盟推送
            PushUtils pushUtils = new PushUtils(imApplication.getUmengKey(), imApplication.getUmengSecret());

            // 安卓单推
            String deviceToken = imClientReceiver.getDeviceToken();
            String unicastText = "Android unicast text";
            String unicastTicker = pushModel.getSubTitle();
            try {
                pushUtils.sendAndroidUnicast(deviceToken, unicastText, unicastTicker, pushModel.getTitle());
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else if (imApplication.getIosPushChannel() == 2) {

            //firebase:2
            log.info("firebase");


            firebase(pushModel, imClientReceiver, imApplication);


        } else if (imApplication.getIosPushChannel() == 3) {
            //  apns原生:3

            log.info("apns原生");
            apnsPush(pushModel, imClientReceiver, imApplication);
        } else {
            log.info("没有找到推送类型");
        }
    }

    public void firebase(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
        String jsonStr = null;
        try {
            URL url = new URL(API_URL_FCM);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setConnectTimeout(10000);
            conn.setRequestMethod("POST");
            //不设置默认发送文本格式。设置就是json
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "key=" + imApplication.getFirebaseSecret());
            JSONObject json = new JSONObject();
            //推送到哪台客户端机器
            json.put("to", imClientReceiver.getDeviceToken());
            JSONObject info = new JSONObject();
            info.put("title", pushModel.getTitle());
            info.put("body", pushModel.getSubTitle());
            //数据消息data  通知消息 notification
            json.put("notification", info);

            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            jsonStr = json.toString();
            wr.write(jsonStr);
            wr.flush();
            InputStream inputStream = conn.getInputStream();
            InputStreamReader in = new InputStreamReader(inputStream);
            BufferedReader reader = new BufferedReader(in);

            String line = reader.readLine();

            log.info(line);

            wr.close();
            reader.close();
        } catch (Exception e) {
            log.error("FCM push failure: " + jsonStr, e);
        }
    }

    private void apnsPush(PushModel pushModel, ImClient imClientReceiver, ImApplication imApplication) {
        // 查询apns证书
        ImIosApns apns = imIosApnsService.getImIosApnsByAppId(imApplication.getId());
        Map<String, Object> customProperty = new HashMap<String, Object>(1);
        String deviceToken = imClientReceiver.getDeviceToken();
        String alertTitle = pushModel.getTitle();
        String alertBody = pushModel.getSubTitle();
        // 统计未读消息数量
        int badge = imInboxService.countMyNotReadCount(imClientReceiver.getId());
        String topicBundleId = apns.getBundleId();
        String certificatePassword = apns.getPwd();
        boolean contentAvailable = false;
        String sound = "default";

        // 解码
        byte[] decode = Base64.decode(apns.getApnsFileValue());
        InputStream inputStream2 = new ByteArrayInputStream(decode);

        //  productFlag      环境,测试=Boolean.FALSE,正式=Boolean.TRUE
        Boolean productFlag = Boolean.FALSE;

        // 正式1,测试0
        if (apns.getEnv() == 1) {
            productFlag = Boolean.TRUE;
        }

        IosPush.push(certificatePassword, inputStream2, productFlag, deviceToken, alertTitle, alertBody,
                contentAvailable, customProperty, badge
                , DeliveryPriority.IMMEDIATE, PushType.ALERT, topicBundleId,
                sound);
    }

}
