package com.aplusinformatique.aplusmanager.Services;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;

import com.aplusinformatique.aplusmanager.R;
import com.honeywell.aidc.AidcManager;
import com.honeywell.aidc.BarcodeFailureEvent;
import com.honeywell.aidc.BarcodeReadEvent;
import com.honeywell.aidc.BarcodeReader;
import com.honeywell.aidc.ScannerUnavailableException;
import com.honeywell.aidc.UnsupportedPropertyException;

public class GererScannerHoneywell extends Service implements BarcodeReader.BarcodeListener {

    private static final String TAG = "distrilog_Honeywell";

    private static BarcodeReader barcodeReader;
    private final Context mContext = this;
    private final String actionActivation = "com.aplusinformatique.aplusmanager.scanneractivation";
    private final String actionReply = "com.aplusinformatique.aplusmanager.scannerreponse";
    //Gestion du Heart Beat (généré par Distrimobile)
    private final String actionAccuseHeartBeat = "com.aplusinformatique.aplusmanager.accuseheartbeat";
    //Broadcast de contrôle d'application Distrimobile toujours active (deprecated)
    private final String actionAccuseReception = "com.aplusinformatique.aplusmanager.accusereception";
    //Broadcast receiver Fin Service
    private final String actionFinService = "com.aplusinformatique.aplusmanager.finservicehoneywell";
    private final int ID_NOTIFICATION = 1004;
    Handler h = new Handler();
    Runnable r;
    private AidcManager manager;
    private BroadcastReceiver receiverActivation;
    private BroadcastReceiver receiverHeartBeat;
    private int accuseHeartBeat = 0;
    private boolean DeclencherFinService = false;
    private BroadcastReceiver receiverAccuseReception;
    private BroadcastReceiver receiverFinService;

    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        Log.d(TAG, "onStartCommand");

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createNotificationChannel(notificationManager) : "";
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.mipmap.taskbar_icon_cb)
                .setContentTitle("Scanner Honeywell")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .build();

        startForeground(ID_NOTIFICATION, notification);

        IntentFilter filterFinService = new IntentFilter();
        filterFinService.addAction(actionFinService);

        receiverFinService = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                FinService();
            }
        };
        registerReceiver(receiverFinService, filterFinService);

        // create the AidcManager providing a Context and a
        // CreatedCallback implementation.
        AidcManager.create(this, new AidcManager.CreatedCallback() {

            @Override
            public void onCreated(AidcManager aidcManager) {
                manager = aidcManager;
                barcodeReader = manager.createBarcodeReader();
                if (barcodeReader != null) {
                    barcodeReader.addBarcodeListener((BarcodeReader.BarcodeListener) mContext);
                    try {
                        barcodeReader.claim();
                    } catch (ScannerUnavailableException e) {
                        e.printStackTrace();
                        Log.d(TAG, "can't claim barcodereader");
                    }
                } else {
                    Log.d(TAG, "can't create barcodereader object");
                }
            }
        });

        IntentFilter filter = new IntentFilter();
        filter.addAction(actionActivation);

        receiverActivation = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                int valeur = Integer.valueOf(intent.getExtras().getString("valeur", "0"));
                ActivationScanner(valeur);
            }
        };
        registerReceiver(receiverActivation, filter);

//        IntentFilter FilterAccuseReception = new IntentFilter();
//        FilterAccuseReception.addAction(actionAccuseReception);
//
//        receiverAccuseReception = new BroadcastReceiver() {
//            @Override
//            public void onReceive(Context context, Intent intent) {
//                accuseReception = 0;
//            }
//        };
//        registerReceiver(receiverAccuseReception, FilterAccuseReception);

//        h.postDelayed(r = new Runnable() {
//            public void run() {
//                boolean FinService = ControleAccuseReception();
//                if (FinService) {
//                    stopSelf();
//                } else {
//                    h.postDelayed(this, 10 * 1000);
//                }
//            }
//        }, 10 * 1000);

        IntentFilter FilterHeartBeat = new IntentFilter();
        FilterHeartBeat.addAction(actionAccuseHeartBeat);

        receiverHeartBeat = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                accuseHeartBeat = 0;
            }
        };
        registerReceiver(receiverHeartBeat, FilterHeartBeat);

        IntentFilter FilterAccuseReception = new IntentFilter();
        FilterAccuseReception.addAction(actionAccuseReception);

        receiverAccuseReception = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                accuseHeartBeat = 0;
            }
        };
        registerReceiver(receiverAccuseReception, FilterAccuseReception);

        //Si l'application Distrimobile ne réponds pas aux intent, on tue le service
        //Contrôle toutes les 5 secondes
        h.postDelayed(r = new Runnable() {
            public void run() {

                accuseHeartBeat += 1;
                Log.d(TAG, "compteur accusé heartbeat : " + String.valueOf(accuseHeartBeat));
                if (accuseHeartBeat > 4) {
                    Log.d(TAG, "accusés sans réponses");
                    DeclencherFinService = true;
                }

                if (DeclencherFinService) {
                    FinService();
                } else {
                    h.postDelayed(this, 5 * 1000);
                }
            }
        }, 5 * 1000);

        return START_STICKY;
    }

    private void ActivationScanner(int valeur) {
        try {
            if (valeur == 0) {
                barcodeReader.setProperty(BarcodeReader.PROPERTY_TRIGGER_CONTROL_MODE, barcodeReader.TRIGGER_CONTROL_MODE_DISABLE);
            } else {
                barcodeReader.setProperty(BarcodeReader.PROPERTY_TRIGGER_CONTROL_MODE, barcodeReader.TRIGGER_CONTROL_MODE_AUTO_CONTROL);
            }
        } catch (UnsupportedPropertyException e) {
            e.printStackTrace();
        }
    }

//    private boolean ControleAccuseReception() {
//
//        Log.d("distrimobile", "ControleAccuseReception GererScannerHoneywell");
//        accuseReception += 1;
//        Log.d("distrimobile","GererScannerHoneywell compteur accuse réception : " + String.valueOf(accuseReception));
//        if (accuseReception > 2) {
//            Log.d("distrimobile", "GererScannerHoneywell accusés sans réponses");
//            return true;
//        }
//        return false;
//    }

    @Override
    public void onBarcodeEvent(BarcodeReadEvent barcodeReadEvent) {
        String barcodeData = barcodeReadEvent.getBarcodeData();

        Log.d(TAG, "lecture CAB Honeywell : " + barcodeData);
        Intent replyIntent = new Intent();
        replyIntent.setAction(actionReply);
        replyIntent.putExtra("data", barcodeData);
        sendBroadcast(replyIntent);
    }

    @Override
    public void onFailureEvent(BarcodeFailureEvent barcodeFailureEvent) {
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");

        if (h != null) {
            h.removeCallbacks(r);
        }

        // unregister barcode event listener
        if (barcodeReader != null) {
            barcodeReader.removeBarcodeListener(this);
            barcodeReader.release();
            barcodeReader.close();
            barcodeReader = null;
        }

        if (manager != null) {
            manager.close();
            manager = null;
        }

        if (receiverActivation != null) {
            unregisterReceiver(receiverActivation);
            receiverActivation = null;
        }

        if (receiverAccuseReception != null) {
            unregisterReceiver(receiverAccuseReception);
            receiverAccuseReception = null;
        }

        if (receiverHeartBeat != null) {
            unregisterReceiver(receiverHeartBeat);
            receiverHeartBeat = null;
        }

        if (receiverFinService != null) {
            unregisterReceiver(receiverFinService);
            receiverFinService = null;
        }

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private String createNotificationChannel(NotificationManager notificationManager) {
        String channelId = TAG;
        String channelName = "Scanner Honeywell";
        NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
        // omitted the LED color
        channel.setImportance(NotificationManager.IMPORTANCE_LOW);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        notificationManager.createNotificationChannel(channel);
        return channelId;
    }

    private void FinService() {
        stopForeground(true);
        stopSelf();
    }
}
