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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
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;
    }

    public void disableSystemMessages() {
        try {
            // Commande ESC/POS pour désactiver les messages d'erreur système
            // Format standard Sunmi : 1F 11 12 n (n=0 pour désactiver)
            byte[] command = new byte[]{0x1F, 0x11, 0x12, 0x00};

            sunmiPrinter.sendRAWData(command, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) {
                    Log.d(TAG, "Messages système désactivés via RAW : " + isSuccess);
                }
                @Override
                public void onReturnString(String result) {}
                @Override
                public void onRaiseException(int code, String msg) {}
                @Override
                public void onPrintResult(int code, String msg) {}
            });
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    // 🔌 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) {

                }

                @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) {
            Log.e(TAG, "Fassery: "+e.getMessage());
            if (listener != null) {
                listener.onError(e.getMessage());
            }
        }
    }

    public int getMaxChar(){
        return MAX_CHAR_2_INCH;
    }

    public void printPari(Bitmap logo, Bitmap barcode, String numeroTicket, String text, PrintStatusListener listener){
        try{
            sunmiPrinter.enterPrinterBuffer(true);
            printSimpleImage(logo);
            printTextSimple("\n" + separationText() + "\n");
            printSimpleImage(barcode);
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }
                @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 onSuccess(boolean isSuccess) {
                }

                @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 onSuccess(boolean isSuccess) {

                }
                @Override
                public void onResult(int code) {}
                @Override
                public void onError(String errorMessage) {}
            });
            printTextSimple("Powered by PMU-MALI");
            printTextSimple("\n" + separationText() + "\n");
            printTextSimple(" ");
            printTextSimple(" ");
            sunmiPrinter.exitPrinterBufferWithCallback(true, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) throws RemoteException {

                }

                @Override
                public void onReturnString(String result) throws RemoteException {
                    Log.e(TAG, "onReturnString: "+result);
                }

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

                }

                @Override
                public void onPrintResult(int code, String msg) throws RemoteException {
                    listener.onStatusChanged(code == 0);
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void printSold(Bitmap logo, String title, StringBuilder text, PrintStatusListener listener){
        try{
            sunmiPrinter.enterPrinterBuffer(true);
            printSimpleImage(logo);
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }
                @Override
                public void onResult(int code) {

                }
                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple("\n" + separationText() + "\n");
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }
                @Override
                public void onResult(int code) {

                }
                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(title);
            printTextSimple("\n"+separationText()+"\n");
            setAlignment(0, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }
                @Override
                public void onResult(int code) {

                }
                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(text.toString());
            printTextSimple("\n" + separationText() + "\n");
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }
                @Override
                public void onResult(int code) {}
                @Override
                public void onError(String errorMessage) {}
            });
            printTextSimple("Powered by PMU-MALI");
            printTextSimple("\n" + separationText() + "\n");
            printTextSimple(" ");
            printTextSimple(" ");
            sunmiPrinter.exitPrinterBufferWithCallback(true, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) throws RemoteException {

                }

                @Override
                public void onReturnString(String result) throws RemoteException {
                    Log.e(TAG, "onReturnString: "+result);
                }

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

                }

                @Override
                public void onPrintResult(int code, String msg) throws RemoteException {
                    listener.onStatusChanged(code == 0);
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void printRapport(Bitmap logo, String courseCode, String hippodromeName, String courseName, String arrivee, String nonPartants, StringBuilder text, PrintStatusListener listener){
        try{
            sunmiPrinter.enterPrinterBuffer(true);
            printSimpleImage(logo);
            printTextSimple(separationText());
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(courseCode);
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(hippodromeName);
            printTextSimple(courseName);
            printTextSimple(separationText());
            setAlignment(0, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple("ARRIVEE    : "+ arrivee);
            setAlignment(0, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple("NON PARTANTS : "+ nonPartants);
            printTextSimple(separationText());
            setAlignment(0, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple(text.toString());
            printTextSimple(separationText());
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple("DATE   : "+ DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(LocalDateTime.now()));
            printTextSimple(separationText());
            setAlignment(1, new PrinterListener() {
                @Override
                public void onSuccess(boolean isSuccess) {

                }

                @Override
                public void onResult(int code) {

                }

                @Override
                public void onError(String errorMessage) {

                }
            });
            printTextSimple("Powered by PMU-MALI");
            printTextSimple(separationText());
            printTextSimple(" ");
            printTextSimple(" ");
            printTextSimple(" ");
            sunmiPrinter.exitPrinterBufferWithCallback(true, new InnerResultCallback() {
                @Override
                public void onRunResult(boolean isSuccess) throws RemoteException {

                }

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

                }

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

                }

                @Override
                public void onPrintResult(int code, String msg) throws RemoteException {
                    listener.onStatusChanged(code == 0);
                }
            });
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    private boolean readyForPrinting(){
        return printerStatus() == 1;
    }

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


    public void printSimpleImage(Bitmap bitmap){
        printImage(bitmap, new PrinterListener() {
            @Override
            public void onSuccess(boolean isSuccess) {}
            @Override
            public void onResult(int code) {}
            @Override
            public void onError(String errorMessage) {}
        });
    }

    // version simple
    public void printTextSimple(String text) {
        printText(text, new PrinterListener() {
            @Override
            public void onSuccess(boolean isSuccess) {}
            @Override
            public void onResult(int code) {}

            @Override
            public void onError(String 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) {}

                @Override
                public void onReturnString(String result) {}

                @Override
                public void onRaiseException(int code, String msg) {
                    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 PrintStatusListener {
        void onStatusChanged(boolean status);
    }

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