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.aplusinformatique.aplusmanager.Tools.Constants;

import java.io.UnsupportedEncodingException;

public class GererScannerBM180 extends Service {

    private static final String TAG = "distrimobilelog_BM180";
    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.finservicebm180";
    private final int ID_NOTIFICATION = 1003;
    Handler h = new Handler();
    Runnable r;
    private BroadcastReceiver receiverActivation;
    private BroadcastReceiver receiverDecodingData;
    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("distrimobile", "Gerer Scanner BM180");

        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 BM180")
                .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);

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

        IntentFilter filterDecodingData = new IntentFilter();
        filterDecodingData.addAction(Constants.ACTION_BARCODE_CALLBACK_DECODING_DATA);
        receiverDecodingData = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                byte[] data = intent.getByteArrayExtra(Constants.EXTRA_BARCODE_DECODING_DATA);
                String dataResult = "";
                if (data != null) {
                    dataResult = new String(data);
                    if (dataResult.contains("�")) {
                        try {
                            dataResult = new String(data, "Shift-JIS");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
                Log.d("distrimobile", "lecture CAB BM180 : " + dataResult);
                Intent replyIntent = new Intent();
                replyIntent.setAction(actionReply);
                replyIntent.putExtra("data", dataResult);
                sendBroadcast(replyIntent);
            }
        };
        registerReceiver(receiverDecodingData, filterDecodingData);

        initScanner();

        return START_STICKY;
    }

    private void initScanner() {
        //Désactivation Datawedge
        Intent i = new Intent("kr.co.bluebird.android.bbapi.action.BARCODE_SET_DATAWEDGE_MODE");
        i.putExtra(Constants.EXTRA_INT_DATA2, 0);
        i.putExtra(Constants.EXTRA_INT_DATA3, 800);
        sendBroadcast(i);

        ActivationScanner(1);
    }

    private void ActivationScanner(int valeur) {
        Intent intent = new Intent();
        if (valeur == 0) {
            intent.setAction(Constants.ACTION_BARCODE_CLOSE);
            intent.putExtra(Constants.EXTRA_INT_DATA3, 200);
        } else if (valeur == 1) {
            intent.setAction(Constants.ACTION_BARCODE_OPEN);
            intent.putExtra(Constants.EXTRA_INT_DATA3, 100);
        }
        sendBroadcast(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("distrimobile", "onDestroy service BM180");

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

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

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

        if (receiverDecodingData != null) {
            unregisterReceiver(receiverDecodingData);
            receiverDecodingData = 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 BM180";
        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();
    }
}
