package com.dspread.pos.ui.cashier;

import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableBoolean;
import androidx.databinding.ObservableField;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.dspread.pos.common.base.BaseAppViewModel;
import com.dspread.pos.data.local.PreferencesManager;
import com.dspread.pos.printerAPI.PrinterHelper;
import com.dspread.print.device.PrintListener;
import com.dspread.print.device.PrinterDevice;
import com.dspread.print.device.PrinterManager;
import com.dspread.print.device.PrinterInitListener;

import org.json.JSONException;
import org.json.JSONObject;

public class CashierViewModel extends BaseAppViewModel {

    // Enum to represent payment status
    public enum PaymentStatus {
        WAITING, SUCCESS, FAILED, PRINTER_NOT_AVAILABLE
    }
    private static final String TAG = "CashierVM";
    private final MutableLiveData<String> paymentInfo = new MutableLiveData<>();
    public LiveData<String> getPaymentInfo() {
        return paymentInfo;
    }
    public ObservableField<String> amount = new ObservableField<>("0.00");
    public ObservableField<String> currencyCode = new ObservableField<>("RUB");
    private final MutableLiveData<PaymentStatus> paymentStatus = new MutableLiveData<>(PaymentStatus.WAITING);
    public LiveData<PaymentStatus> getPaymentStatus() {
        return paymentStatus;
    }
    public final ObservableField<Integer> mainLogo = new ObservableField<>();
    public final ObservableField<Bitmap> mainLogoBitmap = new ObservableField<>();
    public ObservableBoolean isPrinting = new ObservableBoolean(false);
    private Context mContext;

    protected PrinterDevice mPrinter;

    public CashierViewModel(@NonNull Application application) {
        super(application);
        mContext = application.getApplicationContext();
        initializePrinter();
}

    private void initializePrinter() {
        try {
            PrinterManager instance = PrinterManager.getInstance();
            mPrinter = instance.getPrinter();

            if (mPrinter != null) {
                PrinterHelper.getInstance().setPrinter(mPrinter);
                PrinterHelper.getInstance().initPrinter(mContext);

                // Set print listener
                mPrinter.setPrintListener(new PrintListener() {
                    @Override
                    public void printResult(boolean success, String message, PrinterDevice.ResultType resultType) {
                        Log.d(TAG, "Print result: " + success + ", Message: " + message);
                        isPrinting.set(false);

                        if (success) {
                            paymentStatus.setValue(PaymentStatus.SUCCESS);
                            Log.d(TAG, "Receipt printed successfully");
                        } else {
                            paymentStatus.setValue(PaymentStatus.FAILED);
                            Log.e(TAG, "Receipt printing failed: " + message);
                        }
                    }
                });

                Log.d(TAG, "Printer initialized successfully");
            } else {
                Log.e(TAG, "Printer device not available");
                paymentStatus.setValue(PaymentStatus.PRINTER_NOT_AVAILABLE);
            }

        } catch (Exception e) {
            Log.e(TAG, "Error initializing printer: " + e.getMessage());
            paymentStatus.setValue(PaymentStatus.PRINTER_NOT_AVAILABLE);
        }
    }

    public void printReceipt() {
        String amountValue = amount.get();
        String currencyCodeValue = currencyCode.get();

        if (amountValue == null || currencyCodeValue == null) {
            Log.d(TAG, "No payment info to print");
            return;
        }

        Log.d(TAG, "Printing Receipt: " + amountValue + " " + currencyCodeValue);

        // Check if printer is available
        if (mPrinter == null) {
            Log.e(TAG, "Printer not available");
            paymentStatus.setValue(PaymentStatus.PRINTER_NOT_AVAILABLE);
            return;
        }

        isPrinting.set(true);
        paymentStatus.setValue(PaymentStatus.WAITING);

        try {
            double amountDouble = Double.parseDouble(amountValue);

            // Execute the print command
            PrinterHelper.getInstance().printReceipt(
                    mContext,
                    prefs,
                    amountDouble,
                    currencyCodeValue,
                    "Cashier",
                    "www.mulberrypos.ru",
                    "www.mulberrypos.ru"
            );

        } catch (NumberFormatException e) {
            Log.e(TAG, "Invalid amount format: " + amountValue);
            isPrinting.set(false);
            paymentStatus.setValue(PaymentStatus.FAILED);
        } catch (RemoteException e) {
            Log.e(TAG, "Remote exception during printing: " + e.getMessage());
            isPrinting.set(false);
            paymentStatus.setValue(PaymentStatus.FAILED);
        } catch (Exception e) {
            Log.e(TAG, "Unexpected error during printing: " + e.getMessage());
            isPrinting.set(false);
            paymentStatus.setValue(PaymentStatus.FAILED);
        }
    }

    // Method to reinitialize printer if connection is lost
    public void reinitializePrinter() {
        initializePrinter();
    }

    // Check if printer is available
    public boolean isPrinterAvailable() {
        return mPrinter != null;
    }

    // Get printer status
    public void checkPrinterStatus() {
        try {
            if (mPrinter != null) {
                PrinterHelper.getInstance().getPrinterStatus();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Error checking printer status: " + e.getMessage());
        }
    }


    @Override
    protected void onPaymentRedirected(String jsonString) {
        Log.d(TAG, "onPaymentRedirected - processing redirect payment");
        Log.d(TAG, "jsonString" + jsonString);

        try {
            JSONObject results = new JSONObject(jsonString);
            PreferencesManager prefs = PreferencesManager.getInstance(getApplication());
            prefs.saveString("lastPaymentRedirectResults", jsonString);

            // Update amount and currency
            amount.set(results.optString("amount", "0.00"));
            currencyCode.set(results.optString("currencySymbol", "RUB"));;

            String status = results.optString("status", "");
            switch (status) {
                case "success":
                    Log.d(TAG, "Redirect Payment Success");
                    paymentStatus.setValue(PaymentStatus.SUCCESS);
                    printReceipt();
                    break;
                case "failed":
                    Log.d(TAG, "Redirect Payment Failed");
                    paymentStatus.setValue(PaymentStatus.FAILED);
                    break;
                default:
                    Log.w(TAG, "Unknown JSON type: " + status);
                    paymentStatus.setValue(PaymentStatus.WAITING);
            }
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing JSON", e);
//            paymentStatus.setValue(PaymentStatus.FAILED);
        }

    }


    // Add this method to your existing CashierViewModel class:
    public void sendMessage(String message) {
        try {
            sendWebSocketMessage(message);

        } catch (Exception e) {
            Log.e(TAG, "Error sending WebSocket message", e);
        }
    }

}
