package com.sipai.jspatrol.Service;

import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.WindowManager;

import androidx.core.app.NotificationCompat;

import com.sipai.jspatrol.Bean.Biz;
import com.sipai.jspatrol.Bean.Patrol;
import com.sipai.jspatrol.Bean.PatrolModel;
import com.sipai.jspatrol.R;
import com.sipai.jspatrol.ShowNotification.LockScreenDialogActivity;
import com.sipai.jspatrol.URL.MethodURL;
import com.sipai.jspatrol.utils.DateFormatUtils;
import com.sipai.jspatrol.utils.EncryptUtils;
import com.sipai.jspatrol.utils.OKHttpUtils;
import com.sipai.jspatrol.utils.RandomStringUtils;
import com.sipai.jspatrol.utils.okHttpCookie.CookiesManager;

import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import info.mqtt.android.service.MqttAndroidClient;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class IPatrolService extends Service {
    private String mServer;
    private String mUserid;
    private String mBizid;
    private String token;
    private String mUsername;
    private String mPwd;
    private String androidId = "";
    private String bizs;
    private List<Biz> bizList = new ArrayList<>();
    //巡检类型
    private String patrolType;//Product("P","生产巡检"), Equipment( "E","设备巡检"), Administrator("A","管理组"),Maintenance("M","运维组");
    private String all;
    private String unsub;
    private String sub;
    private List<Patrol> daily_patrols = new ArrayList<>();
    private List<Patrol> now_patrols = new ArrayList<>();
    public static final String update_task = "broadcast_update_task";
    //任务提醒
    private NotificationManager manager;
    private Notification notification;
    private String channelName = "com_patrol_task";
    private String channelID = "64368180";
    private static final int NOTIF = 12;

    MqttAndroidClient mqttAndroidClient;
    private String title_msg = "";
    private String content_msg = "";
    private String serverUri = "ws://116.228.107.170:9291";
    String clientId = "";
    public static final String update_newvalue = "broadcast_update_newvalue";
    public static final String update_biz = "broadcast_update_biz";

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case NOTIF:
                    Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALL);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
                        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                        manager.createNotificationChannel(channel);
                        Notification.Builder builder = new Notification.Builder(IPatrolService.this);
                        builder.setChannelId(channelID);
                        Notification notification = builder
                                .setSound(uri)
                                .setContentTitle("新任务")
                                .setContentText("您有新的巡检任务，请及时处理！")
                                .setWhen(System.currentTimeMillis())
                                .setSmallIcon(R.mipmap.moudle_ipatrol_logo)
                                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.moudle_ipatrol_logo))
                                .setDefaults(NotificationCompat.DEFAULT_VIBRATE)
                                .setAutoCancel(true)
                                .build();
                        manager.notify(1, notification);
                    } else {
                        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                        Notification notification = new Notification.Builder(IPatrolService.this)
                                .setSound(uri)
                                .setContentTitle("新任务")
                                .setContentText("您有新的巡检任务，请及时处理！")
                                .setWhen(System.currentTimeMillis())
                                .setSmallIcon(R.mipmap.moudle_ipatrol_logo)
                                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.moudle_ipatrol_logo))
                                .setPriority(Notification.PRIORITY_DEFAULT)
                                .setAutoCancel(true)
                                .build();
                        manager.notify(1, notification);
                    }

                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(IPatrolService.this);
                    alertDialog.setTitle("新的巡检任务开始啦!");
                    alertDialog.setMessage(now_patrols.get(0).getName());
                    final Dialog dialog = alertDialog.create();
                    alertDialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {
                            // TODO Auto-generated method stub
                        }
                    });
                    AlertDialog ad = alertDialog.create();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        ad.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
                    } else {
                        ad.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                    }
                    ad.setCanceledOnTouchOutside(false);                                   //点击外面区域不会让dialog消失
                    ad.show();
                    break;
            }
        }
    };


    public IPatrolService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initBroadcast();
        init();
    }

    private void initBroadcast() {
        IntentFilter filte = new IntentFilter();
        filte.addAction(IPatrolService.update_biz);
        registerReceiver(InfoReceiver, filte);
    }

    BroadcastReceiver InfoReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            init();
        }
    };

    public void subscribeToTopic() {
        try {
            if (mBizid.equals(bizList.get(0).getBizid())){
                bizList.remove(0);
                int[] Qos = new int[bizList.size()];
                String[] topic = new String[bizList.size()];
                for (int i=0;i<bizList.size();i++){
                    Qos[i] = 1;
                    topic[i] = bizList.get(i).getBizid()+"_01_UP_VIEW";
                }
                mqttAndroidClient.subscribe(topic, Qos, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        Log.i("mouse","订阅成功");
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        Log.i("mouse","订阅失败");
                    }
                });
            }else {
                int[] Qos = {1};
//            String[] topic = {mUserid,"021SSXC_01_UP_VUE","alarm_popup_topic_"+mUserid,"personTopic"};
                String[] topic = {mBizid+"_01_UP_VIEW"};
                //开始订阅
                mqttAndroidClient.subscribe(topic, Qos, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        Log.i("mouse","订阅成功");
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        Log.i("mouse","订阅失败");
                    }
                });
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    private void dy() {
        //新建client实例
        clientId = RandomStringUtils.getStrNumRandom(18);
        mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), serverUri, clientId);
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setCleanSession(true);

        try {
            //连接mqtt服务器
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i("mouse","连接成功");
                    //订阅topic
                    subscribeToTopic();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i("mouse","连接失败！！！"+exception.getMessage());
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        MqttCallbackExtended callbackExtended = new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                if (reconnect) {
//                    Toast.makeText(MainActivity.this, "重连订阅", Toast.LENGTH_SHORT).show();
                    //当发生断线之后又重新连接的情况，reconnect会返回true，初次连接成功返回的是false
                    subscribeToTopic();
                }

            }

            @Override
            public void connectionLost(Throwable cause) {
                //连接异常将会回调这个方法
//                Log.i("mouse", "connectionLost: 链接异常，"+cause.toString());
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                String nValue = new String(message.getPayload(),"GB2312");
                Log.i("mouse", "messageArrived: "+nValue);
                //打印订阅的消息
                    Intent intent = new Intent(update_newvalue);
                    intent.putExtra("newvalue", nValue);
                    sendBroadcast(intent);
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {

            }
        };

        mqttAndroidClient.setCallback(callbackExtended);
    }

    private void init() {
        SharedPreferences sharedPre=getSharedPreferences("config", MODE_PRIVATE);
        mServer=sharedPre.getString("server", "");
        mUserid=sharedPre.getString("userid", "");
        mBizid=sharedPre.getString("bizid", "");
        mUsername=sharedPre.getString("username", "");
        mPwd=sharedPre.getString("password", "");
        androidId = Settings.System.getString(
                getContentResolver(), Settings.Secure.ANDROID_ID);
        bizs = sharedPre.getString("biz","");
        bizList = parseBiz(bizs);
        patrolType = sharedPre.getString("patrolTypeId","");
        token = sharedPre.getString("token","");
        if (mqttAndroidClient!=null){
            try {
                mqttAndroidClient.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        dy();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                getPatrolTask();
            }
        }).start();
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        int anS = 59 * 1000;
        long triggerAtTime = SystemClock.elapsedRealtime() + anS;
        Intent i = new Intent(this, IPatrolService.class);
        PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
        if (android.os.Build.VERSION.SDK_INT > 22) {
            manager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        } else if (android.os.Build.VERSION.SDK_INT > 18) {
            manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        } else {
            manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private List<Biz> parseBiz(String result) {
        List<Biz> list = new ArrayList<>();
        try {
            JSONArray array = new JSONArray(result);
            for (int i=0;i<array.length();i++){
                Biz item = new Biz();
                item.setId(array.getJSONObject(i).optString("id"));
                item.setBizid(array.getJSONObject(i).optString("id"));
                item.setName(array.getJSONObject(i).optString("text"));
                list.add(item);
            }
        } catch (JSONException e) {
            e.printStackTrace();
            return list;
        }
        return list;
    }

    private void getPatrolTask() {
        HashMap<String,String> map = new HashMap<>();
        map.put("unitId",mBizid);
        map.put("userIds",mUserid);
        map.put("bizid",mBizid);
        map.put("type","P");
        OKHttpUtils.OKCallGet(map, mServer, MethodURL.GetPatrolList_Method).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String res = response.body().string();
                if (!res.contains("fail")&&res.contains("allNum")) {
                    daily_patrols = getDailyPatrols(res);
                    if (daily_patrols.size()>0){
                        List<Patrol> nowPatrols = checkPatrols(daily_patrols);
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String now = df.format(new Date());
                        now_patrols.clear();
                        for (int i=0;i<nowPatrols.size();i++){
                            if (DateFormatUtils.DateFormatMinString(nowPatrols.get(i).getStartTime()).equals(DateFormatUtils.DateFormatMinString(now))){
                                now_patrols.add(nowPatrols.get(i));
                            }
                        }
                        if (now_patrols.size()>0){
                            PushNotification(now_patrols);
                        }
                        if (nowPatrols.size()==0){
                            Patrol patrol = new Patrol();
                            patrol.setContent("暂无任务");
                            patrol.setEndTime("");
                            patrol.setName("暂无任务");
                            patrol.setStartTime("");
                            nowPatrols.add(patrol);
//                            patrol.setStatus(arry.getJSONObject(i).opt("status").toString());
                        }
                        Intent intent = new Intent(update_task);
                        intent.putExtra("all",all);
                        intent.putExtra("unsub",unsub);
                        intent.putExtra("sub",sub);
                        intent.putExtra("tasks", (Serializable) nowPatrols);
                        sendBroadcast(intent);
                    }
                }else if (res.contains("html")){
                    login("task");
                }
            }
        });
    }

    private void login(String mark) {
        CookiesManager.clearCookie(getApplicationContext());
        HashMap<String,String> map = new HashMap<>();
        String p_pwd = "";
        String vcode = "";
        String code = RandomStringUtils.getRandomStr(1,4);
        try {
            vcode = "64368180";
            vcode = "64368180"+code;
            vcode = EncryptUtils.encrypt(vcode).replace("\n","");
            code = EncryptUtils.encrypt(code).replace("\n","");
            vcode = URLEncoder.encode(vcode,"UTF-8");
            code = URLEncoder.encode(code,"UTF-8");
            p_pwd = URLEncoder.encode(mPwd,"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("j_password",p_pwd);
        map.put("j_username",mUsername);
        map.put("androidId",androidId);
        map.put("verCode",vcode);
        map.put("code",code);
        OKHttpUtils.OKCallGet(map,mServer,MethodURL.Login_Method).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("IPatrol", "onFailure: "+e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                if (mark.equals("task")){
                    getPatrolTask();
                }
            }
        });
    }

    private void PushNotification(List<Patrol> nowPatrols) {
        manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notification = new Notification(R.mipmap.moudle_ipatrol_logo, nowPatrols.get(0).getContent(),
                System.currentTimeMillis());

        notification.defaults = Notification.DEFAULT_ALL; //
        notification.flags = Notification.FLAG_AUTO_CANCEL; //
        notification.flags |= Notification.FLAG_NO_CLEAR;//

        notification = new Notification.Builder(this)
                .setTicker(nowPatrols.get(0).getContent()).setSmallIcon(R.mipmap.moudle_ipatrol_logo).setWhen(System.currentTimeMillis())
                .setContentTitle("新的巡检任务开始啦!").setContentText(nowPatrols.get(0).getName()).build();


        manager.notify(0, notification);

        //弹窗
        KeyguardManager km = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE);
        if (km.inKeyguardRestrictedInputMode()) {
            LockScreenDialogActivity.actionStart(this,nowPatrols.get(0).getName(),nowPatrols.get(0).getContent());
//            Intent alarmIntent = new Intent(this, LockScreenDialogActivity.class);
//            alarmIntent.putExtra("title", "巡检任务");
//            alarmIntent.putExtra("info", "您有新的巡检任务：\n" + nowPatrols.get(0).getName());
//            alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
//            startActivity(alarmIntent);
        } else {
            Message msg = new Message();
            msg.what = NOTIF;
            handler.sendMessage(msg);

        }
    }

    private List<Patrol> checkPatrols(List<Patrol> daily_patrols) {
        List<Patrol> list = new ArrayList<>();
        for (int i=0;i<daily_patrols.size();i++){
            Patrol item = daily_patrols.get(i);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date curDate = new Date(System.currentTimeMillis());
            Calendar cnow = Calendar.getInstance();
            Calendar cstart = Calendar.getInstance();
            Calendar cend = Calendar.getInstance();
            int result = 0;
            int result1 = 0;
            try {
                cnow.setTime(curDate);
                cstart.setTime(df.parse(item.getStartTime()));
                cend.setTime(df.parse(item.getEndTime()));
                result = cnow.compareTo(cstart);
                result1 = cnow.compareTo(cend);
                if (result>=0&&result1<=0){
                    list.add(item);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    private List<Patrol> getDailyPatrols(String response) {
        List<Patrol> list = new ArrayList<>();
        try {
            JSONObject jsonObject = new JSONObject(response);
            all = jsonObject.opt("allNum").toString();
            unsub = jsonObject.opt("inCompleteNum").toString();
            sub = jsonObject.opt("completeNum").toString();
            JSONArray arry = new JSONArray(jsonObject.optString("content1"));
            for (int i=0;i<arry.length();i++){
                Patrol patrol = new Patrol();
                patrol.setBizid(arry.getJSONObject(i).opt("bizId").toString());
                patrol.setContent(arry.getJSONObject(i).opt("content").toString());
                patrol.setEndTime(arry.getJSONObject(i).opt("endTime").toString());
                patrol.setSid(arry.getJSONObject(i).opt("id").toString());
                patrol.setName(arry.getJSONObject(i).opt("name").toString());
                patrol.setPatrolArea(arry.getJSONObject(i).opt("patrolArea").toString());
                patrol.setPatrolAreaId(arry.getJSONObject(i).opt("patrolAreaId").toString());
                patrol.setPatrolModelId(arry.getJSONObject(i).opt("patrolModelId").toString());
                patrol.setPatrolPlanId(arry.getJSONObject(i).opt("patrolPlanId").toString());
                patrol.setStartTime(arry.getJSONObject(i).opt("startTime").toString());
                patrol.setStatus(arry.getJSONObject(i).opt("status").toString());
                patrol.setType(arry.getJSONObject(i).opt("type").toString());
                patrol.setWorkResult(arry.getJSONObject(i).opt("workResult").toString());
                patrol.setWorker(arry.getJSONObject(i).opt("worker").toString());
                patrol.setWorkerId(arry.getJSONObject(i).opt("workerId").toString());
                patrol.setPatrolType(patrolType);
                PatrolModel patrolModel = new PatrolModel();
                if (arry.getJSONObject(i).opt("patrolModel")!=null&&!arry.getJSONObject(i).opt("patrolModel").toString().equals("null")) {
                    JSONObject js = new JSONObject(arry.getJSONObject(i).opt("patrolModel").toString());
                    patrolModel.setSid(js.opt("id").toString());
                    patrolModel.setActive(js.opt("active").toString());
                    patrolModel.setBizId(js.opt("bizId").toString());
                    patrolModel.setDefaultFlag(js.opt("defaultFlag").toString());
                    patrolModel.setName(js.opt("name").toString());
                    patrolModel.setType(js.opt("type").toString());
                    patrolModel.setWhere(js.opt("where").toString());
                    patrol.setPatrolModel(patrolModel);
                }else {
                    patrolModel.setSid("");
                    patrolModel.setActive("");
                    patrolModel.setBizId("");
                    patrolModel.setDefaultFlag("");
                    patrolModel.setName("");
                    patrolModel.setType("");
                    patrolModel.setWhere("");
                    patrol.setPatrolModel(patrolModel);
                }
                list.add(patrol);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mqttAndroidClient!=null) {
            mqttAndroidClient.unregisterResources();
        }
        unregisterReceiver(InfoReceiver);
        try {
            Thread.sleep(500);
            if (mqttAndroidClient!=null) {
                mqttAndroidClient.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
