package com.example.quiz.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.RemoteException;
import android.util.Log;

import com.sunmi.peripheral.printer.InnerPrinterCallback;
import com.sunmi.peripheral.printer.InnerPrinterManager;
import com.sunmi.peripheral.printer.InnerResultCallback;
import com.sunmi.peripheral.printer.SunmiPrinterService;

import java.util.List;
import java.util.function.Consumer;

public class SunmiPrinterManager {

    private static final String TAG = "SunmiPrinterManager";
    private static SunmiPrinterManager instance;

    private static final int MAX_CHAR_2_INCH = 32;
    private static Context context;

    private SunmiPrinterService sunmiPrinter;

    private SunmiPrinterManager() {}

    public static SunmiPrinterManager getInstance(Context ctx) {
        if (instance == null) {
            instance = new SunmiPrinterManager();
            context = ctx.getApplicationContext();
        }
        return instance;
    }

    // 🔌 Bind UNE SEULE FOIS
    public void connectPrinter(Consumer<Boolean> status) {
        Log.d("######", "Point d'entrée printer");
        try {
            InnerPrinterManager.getInstance().bindService(context, new InnerPrinterCallback() {
                @Override
                protected void onConnected(SunmiPrinterService service) {
                    Log.d("######", "Connecté printer");
                    sunmiPrinter = service;
                    status.accept(true);
                }

                @Override
                protected void onDisconnected() {
                    Log.d("######", "Déconnecté printer");
                    sunmiPrinter = null;
                    status.accept(false);
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "#################Erreur bindService"+String.valueOf(e));
        }
    }

    // ✅ simple check

    // 🖨️ Impression robuste
    public void printText(String text, PrinterListener listener) {
        try {
            sunmiPrinter.printText(text + "\n", new InnerResultCallback() {

                @Override
                public void onRunResult(boolean isSuccess) {
                    if(!isSuccess){
                        try {
                            throw new Exception("Impression", new Throwable("Erreur lors d'impression!"));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

                @Override
                public void onReturnString(String result) {
                    // rarement utile
                }

                @Override
                public void onRaiseException(int code, String msg) {
                    listener.onError(msg);
                    listener.onResult(code);
                }


                @Override
                public void onPrintResult(int code, String msg) {
                    listener.onResult(code);
                    listener.onError(msg);
                }
            });

        } catch (Exception e) {
            if (listener != null) {
                listener.onError(e.getMessage());
            }
        }
    }

    public int getMaxChar(){
        return MAX_CHAR_2_INCH;
    }

    public boolean printPari(Bitmap logo, Bitmap barcode, String numeroTicket, String text){
        try{
            printSimpleImage(logo);
            printTextSimple("\n"+separationText()+"\n");
            printSimpleImage(barcode);
            setAlignment(1, new PrinterListener() {
                @Override
                public void onResult(int code) {

                }
                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(numeroTicket);
            printTextSimple("\n"+separationText()+"\n");
            setAlignment(0, new PrinterListener() {
                @Override
                public void onResult(int code) {}
                @Override
                public void onError(String errorMessage) {}
            });
            printTextSimple(text);
            printTextSimple("\n"+separationText()+"\n");
            setAlignment(1, new PrinterListener() {
                @Override
                public void onResult(int code) {}
                @Override
                public void onError(String errorMessage) {}
            });
            printTextSimple("Powered by PMU-MALI");
            printTextSimple("\n"+separationText()+"\n");
            printTextSimple(" ");
            printTextSimple(" ");
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String separationText(){
        return "-".repeat(MAX_CHAR_2_INCH);
    }


    public void printSimpleImage(Bitmap bitmap){
        printImage(bitmap, new PrinterListener() {
            @Override
            public void onResult(int code) {
                Log.d(TAG, "Print OK");
            }
            @Override
            public void onError(String errorMessage) {
                Log.e(TAG, errorMessage);
            }
        });
    }

    // version simple
    public void printTextSimple(String text) {
        printText(text, new PrinterListener() {
            @Override
            public void onResult(int code) {
                Log.d(TAG, "Print OK");
            }

            @Override
            public void onError(String errorMessage) {
                Log.e(TAG, errorMessage);
            }
        });
    }

    // Dans SunmiPrinterManager.java

    public void setAlignment(int alignment, PrinterListener listener) {
        try {
            // Appel au SDK Sunmi : 0=gauche, 1=centre, 2=droite
            sunmiPrinter.setAlignment(alignment, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) throws RemoteException {
                    if(!isSuccess){
                        try {
                            throw new Exception("Alignement", new Throwable("L'alignement n'a pas pu être défini"));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

                @Override
                public void onReturnString(String result) throws RemoteException {

                }

                @Override
                public void onRaiseException(int code, String msg) throws RemoteException {
                    listener.onError(msg);
                    listener.onResult(code);
                }

                @Override
                public void onPrintResult(int code, String msg) throws RemoteException {

                }
            });
        } catch (Exception e) {
            if (listener != null) listener.onError(e.getMessage());
        }
    }

    public void printImage(Bitmap bitmap, PrinterListener listener){
        try {
            // La plupart des imprimantes Sunmi utilisent cette méthode
            // Le paramètre '0' correspond généralement à l'alignement (0 = gauche)
            sunmiPrinter.printBitmap(bitmap, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) {
                    if(!isSuccess){
                        try {
                            throw new Exception("Impression", new Throwable("Erreur lors d'impression d'une image!"));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

                @Override
                public void onReturnString(String result) {
                    // Pas utile
                }

                @Override
                public void onRaiseException(int code, String msg) {
                    Log.e(TAG, "onRaiseException: "+String.valueOf(code));
                    listener.onResult(code);
                    listener.onError(msg);
                }

                @Override
                public void onPrintResult(int code, String msg) {
                    Log.e(TAG, "onPrintResult: "+String.valueOf(code));
                   listener.onResult(code);
                   listener.onError(msg);
                }
                // N'oublie pas les autres callbacks vides (onRunResult, etc.)
            });
        } catch (Exception e) {
            listener.onError(e.getMessage());
        }
    }



    public int printerStatus(){
        try {
            return sunmiPrinter.updatePrinterState();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    public interface PrinterListener {
        void onResult(int code);
        void onError(String errorMessage);
    }
}