package com.sunzee.service;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hboxs.serialport.SerialPortDevice;
import com.hboxs.serialport.SerialPortManager;
import com.hboxs.serialport.SerialPortSendQueue;
import com.hboxs.serialport.frame.RstCommandFrame;
import com.hboxs.serialport.frame.SetCommandFrame;
import com.hboxs.serialport.frame.WriteCommandFrame;
import com.hboxs.serialport.message.Message;
import com.hboxs.serialport.util.ByteUtils;
import com.hboxs.serialport.util.HexUtils;
import com.igexin.sdk.GTIntentService;
import com.igexin.sdk.message.GTCmdMessage;
import com.igexin.sdk.message.GTNotificationMessage;
import com.igexin.sdk.message.GTTransmitMessage;
import com.orhanobut.hawk.Hawk;
import com.sunzee.base.BaseApplication;
import com.sunzee.model.Global;
import com.sunzee.model.Heartbeat;
import com.sunzee.model.HttpResult;
import com.sunzee.model.domain.GeTuiBean;
import com.sunzee.model.domain.GetAdBean;
import com.sunzee.model.domain.Name;
import com.sunzee.model.domain.TimeRuleBean;
import com.sunzee.model.message.ApiMessageEvent;
import com.sunzee.retrofit.ApiCallback;
import com.sunzee.retrofit.ApiClient;
import com.sunzee.retrofit.ApiStores;
import com.sunzee.utils.AlarmManagerUtil;
import com.sunzee.utils.SharedPreferencesUtils;
import com.wuxiaolong.androidutils.library.LogUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;


/**
 * 继承 GTIntentService 接收来自个推的消息，所有消息在线程中回调，
 * 如果注册了该服务，则务必要在 AndroidManifest 中声明，否则无法接受消息
 */
public class MyIntentService extends GTIntentService {
    @Override
    public void onReceiveServicePid(Context context, int i) {

    }

    @Subscribe
    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }


    /**
     * 接收 cid
     *
     * @param context  上下文
     * @param clientid 个推id
     */
    @Override
    public void onReceiveClientId(Context context, String clientid) {
        LogUtil.e(TAG, "onReceiveClientId -> " + "clientid = " + clientid);
        Heartbeat.clientId = clientid;
    }

    /**
     * 处理透传消息
     */
    @Override
    public void onReceiveMessageData(Context context, GTTransmitMessage gtTransmitMessage) {

        String appid = gtTransmitMessage.getAppid();
        String taskid = gtTransmitMessage.getTaskId();
        String messageid = gtTransmitMessage.getMessageId();
        byte[] payload = gtTransmitMessage.getPayload();
        String pkg = gtTransmitMessage.getPkgName();
        String cid = gtTransmitMessage.getClientId();

        String data = new String(payload);
        Gson gson = new Gson();
        LogUtil.e(TAG, "onReceiveMessageData: " + ";appid" + appid + ";taskid" + taskid + ";messageid" + messageid + ";payload" + payload + ";pkg" + pkg + ";cid" + cid);
        LogUtil.e(TAG, "onReceiveMessageData: data:" + data);
        LogUtil.e(TAG, "onReceiveMessageData : realData=" + data);
        GeTuiBean geTuiBean = gson.fromJson(data, GeTuiBean.class);
        String kind = geTuiBean.getKind();
        switch (kind) {
            case "clean":
                //一间清洗
                startClean(gson, geTuiBean, kind);
                break;
            case "statusType":
                //申请初始化回调
                statusType(gson, geTuiBean, kind);
                break;
            case "pushTimeRule":
                LogUtil.d(TAG, "MyIntentServicepushTimeRule: ");
                //广告规则
                changeAdRules(geTuiBean);
                break;
            case "Param":
                //更新参数。
                updataParam(gson, geTuiBean, kind);
                break;
            case "updateRule":
                //更新定时清洗的任务
                updataCleanRule(gson, geTuiBean, kind);
                break;
            //不需要更新广告了，而是更具规则来下载广告。
//            case "push":
//                LogUtil.d(TAG, "push: ");
//                //更新广告
//                String json = geTuiBean.getKind_data();
//                if (json.equals("更新广告")) {
//                    saveAd();
//                }
//                break;

        }

    }

    private void updataCleanRule(Gson gson, GeTuiBean geTuiBean, String kind) {
        String times = geTuiBean.getKind_data();

        Log.d(TAG, "闹钟响了26onSuccess: " + times);
        if (!TextUtils.isEmpty(times)) {
            String[] Alltime = times.split("\\,");
            //如果之前的数据和现在的数据，数量相同，或者之前的数据小于现在的数据，，那么不清除直接替换。
            //不可能为0。
            if (Global.alarmNumber>Alltime.length) {
                for (int i = 0; i <Global.alarmNumber ; i++) {
                    AlarmManagerUtil.cancelAlarm(BaseApplication.getContext(),AlarmManagerUtil.ALARM_ACTION,i);
                }
            }
            Global.alarmNumber = Alltime.length;
            for (int i = 0; i < Alltime.length; i++) {
                String[] data = Alltime[i].split(":");
                for (String datum : data) {
                    Log.d(TAG, "onSuccess: " + datum);
                }
                //设置定时闹钟
                AlarmManagerUtil.setAlarm(BaseApplication.getContext(), 1, Integer.valueOf(data[0]), Integer.valueOf(data[1]), Integer.valueOf(data[2]), i, 0, "闹钟响了26");
            }
        }
    }

    private void updataParam(Gson gson, GeTuiBean geTuiBean, String kind) {
        String[] split = geTuiBean.getKind_data().split(":");
        String address = split[0];
        String data = split[1];
        if (!TextUtils.isEmpty(address) || !TextUtils.isEmpty(data)) {
            switch (address) {
                //复位和置位   0为启动，1为关闭。
                case "M311":
                case "M312":
                case "M313":
                case "M315":
                case "M316":
                case "M317":
                case "M318":
                case "M17":
                    if ("0".equals(data)) {
                        startSet(address);
                    } else {
                        startRst(address);
                    }
                    break;
                //写入,写入后需要上传。
                case "D426":
                case "D427":
                case "D428":
                case "D429":
                case "D430":
                case "D431":
                    startWrite(address, data.trim());
                    break;
            }
        }
    }

    private Timer timerWrite;
    private TimerTask timerTaskWrite;

    private void startWrite(final String address, final String data) {
        timerWrite = new Timer();
        timerTaskWrite = new TimerTask() {
            @Override
            public void run() {
                Log.d(TAG, "run: ");
                String text = ByteUtils.decimal2fitHex(Integer.valueOf(data));
                SerialPortManager.getInstance().sendCommandFrame(new WriteCommandFrame(address, HexUtils.hexStr2BinStr(text)), address);
            }
        };
        timerWrite.schedule(timerTaskWrite, 0, 1000);

    }


    private Timer timerSet;
    private TimerTask timerTaskSet;

    private void startSet(final String address) {
        timerSet = new Timer();
        timerTaskSet = new TimerTask() {
            @Override
            public void run() {
                SerialPortSendQueue.sendCommand(new SetCommandFrame(address), 18, address);
                Log.d(TAG, "run: ");
            }
        };
        timerSet.schedule(timerTaskSet, 0, 1000);
    }

    private Timer timerRst;
    private TimerTask timerTaskRst;

    private void startRst(final String address) {
        timerRst = new Timer();
        timerTaskRst = new TimerTask() {
            @Override
            public void run() {
                SerialPortSendQueue.sendCommand(new RstCommandFrame(address), 18, address);
                Log.d(TAG, "run: ");
            }
        };
        timerRst.schedule(timerTaskRst, 0, 1000);
    }

    private void stopSet(Timer timer, TimerTask timerTask) {
        Log.d(TAG, "stopSet: ");
        if (timer != null) {
            timerTask.cancel();
            timer.cancel();
            timer = null;
        }
    }

    private void stopWrite(Timer timer, TimerTask timerTask) {
        Log.d(TAG, "stopWrite: ");
        if (timer != null) {
            timerTask.cancel();
            timer.cancel();
            timer = null;
        }
    }

    private void stopRst(Timer timer, TimerTask timerTask) {
        if (timer != null) {
            timerTask.cancel();
            timer.cancel();
            timer = null;
        }
    }


    private CompositeDisposable mDisposables;
    protected ApiStores apiStores = ApiClient.retrofit().create(ApiStores.class);

    protected void addSubscription(Observable observable, DisposableObserver observer) {
        if (mDisposables == null) {
            mDisposables = new CompositeDisposable();
        }
        observable
                .unsubscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
        mDisposables.add(observer);
    }

    /**
     * 改变广告规则
     *
     * @param geTuiBean 广告规则数据
     */
    private void changeAdRules(GeTuiBean geTuiBean) {
        String json = geTuiBean.getKind_data();
        saveAdRules(json);
    }

    /**
     * 保存广告id
     */
    private void saveAdRules(String id) {
        LogUtil.d(TAG, "ad_id ->" + id);
        Long lid = Long.valueOf(id);
        Map<String, Long> params = new HashMap<>();
        params.put("id", lid);
        addSubscription(apiStores.getTimeRule(params), new ApiCallback<HttpResult<String>>() {

            @Override
            public void onSuccess(HttpResult<String> rule) {
                Log.d(TAG, "onSuccess: ");
                String data = rule.getData();
                //广告数据
                ArrayList<GetAdBean> adBeans = Hawk.get("showAd", new ArrayList<GetAdBean>());
                Gson gson = new Gson();
                Log.d(TAG, "onSuccess: 1" + adBeans);
                List<TimeRuleBean> list = gson.fromJson(data, new TypeToken<List<TimeRuleBean>>() {
                }.getType());
                Log.d(TAG, "onSuccess: 2");
                //每个id对应的时间数
                Map<String, String> adRulesMap = new HashMap<>();
                for (int i = 0; i < adBeans.size(); i++) {
                    GetAdBean getAdBean = adBeans.get(i);
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < list.size(); j++) {
                        //每个规则里对应的广告
                        List<String> ad = list.get(j).getAd();
                        for (int k = 0; k < ad.size(); k++) {
                            if (ad.get(k).equals(getAdBean.getId())) {
                                sb.append(list.get(j).getTime() + "、");
                            }
                        }
                    }
                    if (sb.length() > 0) {
                        sb.deleteCharAt(sb.length() - 1);
                    }
                    LogUtil.e(TAG, "onNext: " + "ad_id=" + getAdBean.getId() + " rules=" + sb.toString());
                    adRulesMap.put(getAdBean.getId(), sb.toString());
                }
                Log.d(TAG, "onSuccess: 3" + adRulesMap);
                //保存对应的id对应的广告规则
                Hawk.put("ad_rules_map", adRulesMap);
                EventBus.getDefault().post(new ApiMessageEvent("pushTimeRule", null));
                //发送设备id
                deviceIdPostApi();
            }

            @Override
            public void onFailure(String msg) {
                Log.d(TAG, "onFailure: ");
            }

            @Override
            public void onFinish() {

            }
        });
    }

    /**
     * 上传设备id,返回该id的的广告资源
     */
    private void deviceIdPostApi() {
        Map<String, String> params = new HashMap<>();
        params.put("clientId", Heartbeat.deviceId + "");
        addSubscription(apiStores.uploadID(params), new ApiCallback<HttpResult<String>>() {

            @Override
            public void onSuccess(HttpResult<String> model) {
                EventBus.getDefault().post(new ApiMessageEvent("DOWNKOADADCID", model.getData()));
            }

            @Override
            public void onFailure(String msg) {
            }

            @Override
            public void onFinish() {

            }
        });
    }

    /**
     * 开始清洗
     *
     * @param gson
     * @param geTuiBean
     * @param kind
     */
    private void startClean(Gson gson, GeTuiBean geTuiBean, String kind) {
        LogUtil.e("home", "statusType: 开始清洗");
    }

    /**
     * 初始化申请连接服务器回调
     *
     * @param gson     格式化
     * @param baseBean 数据类
     * @param kind     携带的数据
     */
    private void statusType(Gson gson, GeTuiBean baseBean, String kind) {
        String json = baseBean.getKind_data();
        String s = gson.fromJson(json, String.class);
        switch (s) {
            case "rejected":
                //拒绝
                SharedPreferencesUtils.setParam(Name.CONNECT_STATE, 0);
                LogUtil.e("home", "statusType: 申请拒绝");
                break;
            case "agreed":
                //申请通过
                SharedPreferencesUtils.setParam(Name.CONNECT_STATE, 2);
                LogUtil.e("home", "statusType: 申请通过");
                SharedPreferencesUtils.setParam(Name.SYSTEM_ID, Heartbeat.managerId);
                break;
            case "agreed1":
                SharedPreferencesUtils.setParam(Name.CONNECT_STATE, 2);
                LogUtil.e("home", "statusType: 申请通过");
                SharedPreferencesUtils.setParam(Name.SYSTEM_ID, Heartbeat.managerId);
                // interService 不能弹出弹窗 在 service中弹出
                EventBus.getDefault().post(new ApiMessageEvent(kind + "1", null));
                break;
        }
        EventBus.getDefault().post(new ApiMessageEvent(kind, null));
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void event(Message messageEvent) {
        switch (messageEvent.getType()) {
            case connected:
                Log.d(TAG, "event: connected");
                break;
            case sendError:
                Log.d(TAG, "event: sendError");
                break;
            case ack:
                Log.d(TAG, "event: 写入成功");
                stopRst(timerRst, timerTaskRst);
                stopSet(timerSet, timerTaskSet);
                stopWrite(timerWrite, timerTaskWrite);
                Log.d(TAG, "event: ack");
                break;
            case nak:
                Log.d(TAG, "event: nak");
                break;
            case disconnected:
                SerialPortDevice device = new SerialPortDevice("/dev/ttyS2", "9600");
                SerialPortManager.getInstance().open(device);
                Log.d(TAG, "event: disconnected");
                break;
            case response:
                Log.d(TAG, "event: response");
                break;
        }
    }

    /**
     * cid 离线上线通知
     */
    @Override
    public void onReceiveOnlineState(Context context, boolean b) {

    }

    /**
     * 各种事件处理回执
     */
    @Override
    public void onReceiveCommandResult(Context context, GTCmdMessage gtCmdMessage) {

    }

    /**
     * 通知到达，只有个推通道下发的通知会回调此方法
     */
    @Override
    public void onNotificationMessageArrived(Context context, GTNotificationMessage gtNotificationMessage) {

    }

    /**
     * 通知点击，只有个推通道下发的通知会回调此方法
     */
    @Override
    public void onNotificationMessageClicked(Context context, GTNotificationMessage gtNotificationMessage) {

    }
}
