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.Bundle;
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;

public class GererScannerZebra extends Service {

    private static final String TAG = "distrimobilelog_Zebra";
    private static final String packageDistrimobile = "com.aplusinformatique.distrimobile_v2";
    // Datawedge API Zebra Actions
    private static final String ACTION_DATAWEDGE = "com.symbol.datawedge.api.ACTION";
    private static final String ACTION_SWITCHTOPROFILE = "com.symbol.datawedge.api.ACTION_SWITCHTOPROFILE";
    private static final String ACTION_SCANNERINPUTPLUGIN = "com.symbol.datawedge.api.ACTION_SCANNERINPUTPLUGIN";
    // Datawedge API Zebra Extras
    private static final String EXTRA_PARAMETER = "com.symbol.datawedge.api.EXTRA_PARAMETER";
    private static final String EXTRA_PROFILENAME = "com.symbol.datawedge.api.EXTRA_PROFILENAME";
    private static final String EXTRA_CREATE_PROFILE = "com.symbol.datawedge.api.CREATE_PROFILE";
    private static final String EXTRA_SET_CONFIG = "com.symbol.datawedge.api.SET_CONFIG";
    private static final String actionReply = "com.aplusinformatique.aplusmanager.scannerreponse";
    private final String actionZebra = "com.aplusinformatique.datawedgezebra";
    //Variables de gestion du service pour Distrimobile
    private final String actionActivation = "com.aplusinformatique.aplusmanager.scanneractivation";
    private final String actionErreurInitialisation = "com.aplusinformatique.aplusmanager.erreurinitscanner";

    //Gestion du Heart Beat (généré par Distrimobile)
    private final String actionAccuseHeartBeat = "com.aplusinformatique.aplusmanager.accuseheartbeat";
    //Broadcast receiver Fin Service
    private final String actionFinService = "com.aplusinformatique.aplusmanager.finservicezebra";
    private final int ID_NOTIFICATION = 1007;
    Handler h = new Handler();
    Runnable r;
    private int accuseHeartBeat = 0;
    private boolean DeclencherFinService = false;
    private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(actionZebra)) {
                String decodedSource = intent.getStringExtra("com.symbol.datawedge.source");
                String decodedData = intent.getStringExtra("com.symbol.datawedge.data_string");
                String decodedLabelType = intent.getStringExtra("com.symbol.datawedge.label_type");

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

            if (action.equals(actionActivation)) {
                int valeur = Integer.valueOf(intent.getExtras().getString("valeur", "0"));
                ActivationScanner(valeur);
            }

            if (action.equals(actionAccuseHeartBeat)) {
                accuseHeartBeat = 0;
            }

            if (action.equals(actionFinService)) {
                FinService();
            }
        }
    };

    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 Zebra")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .build();

        startForeground(ID_NOTIFICATION, notification);

        //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);

        SetDataWedgeProfile("Aplus Informatique");
        ActivationScanner(1);

        // Create a filter for the broadcast intent
        IntentFilter filter = new IntentFilter();
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        filter.addAction(actionZebra);
        filter.addAction(actionActivation);
        filter.addAction(actionAccuseHeartBeat);
        filter.addAction(actionFinService);
        registerReceiver(myBroadcastReceiver, filter);

        return START_STICKY;
    }

    private void SetDataWedgeProfile(String profileName) {

        //Création du profil datawedge
        sendDataWedgeIntentWithExtra(ACTION_DATAWEDGE, EXTRA_CREATE_PROFILE, profileName);

        //Configuration du profil
        Bundle profileConfig = new Bundle();
        profileConfig.putString("PROFILE_NAME", profileName);
        profileConfig.putString("PROFILE_ENABLED", "true"); //  Seems these are all strings
        profileConfig.putString("CONFIG_MODE", "UPDATE");
        Bundle barcodeConfig = new Bundle();
        barcodeConfig.putString("PLUGIN_NAME", "BARCODE");
        barcodeConfig.putString("RESET_CONFIG", "true"); //  This is the default but never hurts to specify
        Bundle barcodeProps = new Bundle();
        barcodeConfig.putBundle("PARAM_LIST", barcodeProps);
        profileConfig.putBundle("PLUGIN_CONFIG", barcodeConfig);
        Bundle appConfig = new Bundle();
        appConfig.putString("PACKAGE_NAME", getPackageName());      //  Associate the profile with this app
        appConfig.putStringArray("ACTIVITY_LIST", new String[]{"*"});
        appConfig.putString("PACKAGE_NAME", packageDistrimobile);
        appConfig.putStringArray("ACTIVITY_LIST", new String[]{"*"});
        profileConfig.putParcelableArray("APP_LIST", new Bundle[]{appConfig});
        sendDataWedgeIntentWithExtra(ACTION_DATAWEDGE, EXTRA_SET_CONFIG, profileConfig);
        //  You can only configure one plugin at a time, we have done the barcode input, now do the intent output
        profileConfig.remove("PLUGIN_CONFIG");
        Bundle intentConfig = new Bundle();
        intentConfig.putString("PLUGIN_NAME", "INTENT");
        intentConfig.putString("RESET_CONFIG", "true");
        Bundle intentProps = new Bundle();
        intentProps.putString("intent_output_enabled", "true");
        intentProps.putString("intent_action", actionZebra);
        intentProps.putString("intent_category", "android.intent.category.DEFAULT");
        intentProps.putString("intent_delivery", "2");
        intentConfig.putBundle("PARAM_LIST", intentProps);
        profileConfig.putBundle("PLUGIN_CONFIG", intentConfig);
        sendDataWedgeIntentWithExtra(ACTION_DATAWEDGE, EXTRA_SET_CONFIG, profileConfig);

        //switch sur le profil
        sendDataWedgeIntentWithExtra(ACTION_SWITCHTOPROFILE, EXTRA_PROFILENAME, profileName);
    }

    private void ActivationScanner(int valeur) {
        String parameter = "";
        if (valeur == 0) {
            parameter = "DISABLE_PLUGIN";
        } else {
            parameter = "ENABLE_PLUGIN";
        }
        sendDataWedgeIntentWithExtra(ACTION_SCANNERINPUTPLUGIN, EXTRA_PARAMETER, parameter);
    }

    private void sendDataWedgeIntentWithExtra(String action, String extraKey, String extraValue) {
        Intent dwIntent = new Intent();
        dwIntent.setAction(action);
        dwIntent.putExtra(extraKey, extraValue);
        sendBroadcast(dwIntent);
    }

    private void sendDataWedgeIntentWithExtra(String action, String extraKey, Bundle extras) {
        Intent dwIntent = new Intent();
        dwIntent.setAction(action);
        dwIntent.putExtra(extraKey, extras);
        this.sendBroadcast(dwIntent);
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private String createNotificationChannel(NotificationManager notificationManager) {
        String channelId = TAG;
        String channelName = "Scanner Zebra";
        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();
    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d(TAG, "onDestroy");

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

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