package com.example.quiz.utils;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.sagereal.printer.PrinterInterface;

import java.io.ByteArrayOutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MobiIotPrinterManager {
    private PrinterInterface mPrinter;
    private static MobiIotPrinterManager instance;
    private boolean isBinding = false;

    private final ExecutorService printExecutor = Executors.newSingleThreadExecutor();
    String TAG = "MOBITAG";

    private static final int MAX_CHAR_2_INCH = 32;

    private MobiIotPrinterManager() {
    }

    public static synchronized MobiIotPrinterManager getInstance() {
        if (instance == null) {
            instance = new MobiIotPrinterManager();
        }
        return instance;
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mPrinter = PrinterInterface.Stub.asInterface(iBinder);
            isBinding = false;
            Log.d("PrinterManager", "✅ Service d'impression connecté !");

            // Test rapide pour voir si l'imprimante répond
            testPrinterStatus();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mPrinter = null;
            Log.d("PrinterManager", "❌ Service d'impression déconnecté.");
        }
    };



    private void testPrinterStatus() {
        new Thread(() -> {
            try {
                if (mPrinter != null) {
                    int status = mPrinter.getPrinterStatus();
                    Log.d("PrinterManager", "Statut imprimante au démarrage : " + status);
                }
            } catch (Exception e) {
                Log.e("PrinterManager", "Erreur test statut", e);
            }
        }).start();
    }

    // Initialisation CORRIGÉE
    public void init(Context context) {
        if (mPrinter != null) {
            Log.d("PrinterManager", "Service déjà connecté");
            return;
        }

        if (isBinding) {
            Log.d("PrinterManager", "Connexion déjà en cours");
            return;
        }

        // Utiliser l'action correcte trouvée dans le dump
        Intent intent = new Intent("sagereal.intent.action.START_PRINTER_SERVICE_AIDL");
        intent.setPackage("com.sagereal.printer");

        try {
            isBinding = true;
            boolean success = context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
            if (!success) {
                isBinding = false;
                Log.e("PrinterManager", "Impossible de binder le service. Vérifiez les permissions.");
            } else {
                Log.d("PrinterManager", "Tentative de connexion au service...");
            }
        } catch (SecurityException e) {
            isBinding = false;
            Log.e("PrinterManager", "Permission refusée. Ajoutez les permissions système.", e);
        }
    }

    public void printText(String text) {
        if (mPrinter == null) {
            Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
            return;
        }

        new Thread(() -> {
            try {
                // Vérifier le statut avant d'imprimer
                int status = mPrinter.getPrinterStatus();
                Log.d("PrinterManager", "Statut avant impression : " + status);

                if (status == 1) { // 0 = Prêt
                    mPrinter.printText(text);
                    mPrinter.printEndLine();
                    Log.d("PrinterManager", "✅ Impression réussie");
                } else {
                    Log.e("PrinterManager", "Imprimante non prête, statut : " + status);

                    Log.e("PrinterManager", "Erreur : Impression non effectuée!");
                }
            } catch (Exception e) {
                Log.e("PrinterManager", "Erreur lors de l'impression", e);
            }
        }).start();
    }

    public void printPari(byte[] logo, byte[] barcode, String numeroTicket, StringBuilder pariText, MobiIotPrinterStatus listener) {
        if (mPrinter == null) {
            Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
            listener.printStatusCode(0);
            return;
        }
        printExecutor.execute(()->{
            try {
                mPrinter.printBitmap_in(logo);
                if(mPrinter.getPrinterStatus() != 1){
                    listener.printStatusCode(0);
                    return;
                }
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printBitmap_in(barcode);
                mPrinter.printText_FullParm("\n" + numeroTicket, 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                //String[] lines = pariText.toString().split("\n");
                mPrinter.printText_FullParm(pariText.toString(), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("Powered by PMU-MALI", 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("\n\n\n\n\n\n", 0, 10, 0, 0, false, false);
                Thread.sleep(3500);
                if(mPrinter.getPrinterStatus() != 1){
                    mPrinter.printText_FullParm("\u001B@", 0, 0, 0, 0, false, false);
                    listener.printStatusCode(0);
                    return;
                }
                listener.printStatusCode(1);
            } catch (RemoteException | InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    public void printSold(byte[] logo, String title, StringBuilder text, MobiIotPrinterStatus listener) throws RemoteException {
        if (mPrinter == null) {
            Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
            listener.printStatusCode(0);
            return;
        }
        printExecutor.execute(()->{
            try {
                mPrinter.printBitmap_in(logo);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(title, 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(text.toString(), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("Powered by PMU-MALI", 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("\n\n\n\n\n\n", 0, 10, 0, 0, false, false);
                Thread.sleep(3500);
                if(mPrinter.getPrinterStatus() != 1){
                    listener.printStatusCode(0);
                    return;
                }
                listener.printStatusCode(1);
            } catch (RemoteException | InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

    }


    public void printRapport(byte[] logo, String courseCode, String hippodromeName, String courseName, String arrivee, String nonPartants, StringBuilder text, MobiIotPrinterStatus listener) throws RemoteException {
        printExecutor.execute(()->{
            try{
                mPrinter.printBitmap_in(logo);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(courseCode, 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(hippodromeName, 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(courseName, 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("ARRIVEE    : "+ arrivee, 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("NON PARTANTS : "+ nonPartants, 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm(text.toString(), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("DATE   : "+ DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(LocalDateTime.now()), 0, 0, 0, 0, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("Powered by PMU-MALI", 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
                mPrinter.printText_FullParm("\n\n\n\n\n\n", 0, 10, 0, 0, false, false);
                Thread.sleep(3500);
                if(mPrinter.getPrinterStatus() != 1){
                    listener.printStatusCode(0);
                    return;
                }
                listener.printStatusCode(1);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    public int getPrinterStatus() throws RemoteException {
        return mPrinter.getPrinterStatus();
    }

    public void printTestText(String text) throws RemoteException {
        Log.d(TAG, "#### " + String.valueOf(mPrinter.getPrinterStatus()));
        mPrinter.printText_FullParm(text, 0, 0, 0, 0, false, false);
    }

    private byte[] pathToPrintableBytes(String path) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        if (bitmap == null) return null;

        // Redimensionnement à 384px (largeur standard 58mm)
        int width = 384;
        int height = (int) (bitmap.getHeight() * (384.0 / bitmap.getWidth()));
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);

        // Conversion en binaire (8 pixels par byte)
        int bwWidth = (width + 7) / 8 * 8;
        byte[] data = new byte[(bwWidth / 8) * height];
        int k = 0;

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < bwWidth; x += 8) {
                byte value = 0;
                for (int bit = 0; bit < 8; bit++) {
                    if (x + bit < scaledBitmap.getWidth()) {
                        int pixel = scaledBitmap.getPixel(x + bit, y);
                        int gray = (int) (Color.red(pixel) * 0.3 + Color.green(pixel) * 0.59 + Color.blue(pixel) * 0.11);
                        if (gray < 128) value |= (1 << (7 - bit));
                    }
                }
                data[k++] = value;
            }
        }
        return data;
    }


    public void disconnect(Context context) {
        if (mPrinter != null) {
            context.unbindService(mConnection);
            mPrinter = null;
            Log.d("PrinterManager", "Service déconnecté");
        }
    }

    public interface MobiIotPrinterStatus {
        void printStatusCode(int status);
    }
}