package com.unibuy.smartdevice.ui.dialog;

import android.content.Context;

import com.unibuy.smartdevice.DialogAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.R;
import com.unibuy.smartdevice.databinding.DialogCustomerIdentifierBinding;
import com.unibuy.smartdevice.devices.DeviceType;
import com.unibuy.smartdevice.devices.UsbDev;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.HandlerMainCountdown;
import com.unibuy.smartdevice.tools.HandlerMainScheduler;
import com.unibuy.smartdevice.tools.ToastHandlerMain;

import java.util.HashMap;
import java.util.Map;

public class InvoiceCustomerIdentifierDialog extends DialogAbstract {
    public enum Option {
        TOAST(0),
        COUNTDOWN_CANCEL(1),
        SET_COUNTDOWN_TEXT(2),
        INVOICE_SUCCESSFUL(4),
        INVOICE_FAILED(5),
        CHANGE_DISPATCH(6),
        CHANGE_BUY(7),
        CHANGE_CHECKOUT(8),
        ;

        private int option;

        public int getOption() {
            return option;
        }

        Option(int option) {
            this.option = option;
        }
    }

    public static final Map<Integer, Option> optionMap = new HashMap<>();
    static {
        for (Option option : Option.values()) {
            optionMap.put(option.getOption(), option);
        }
    }

    @Override
    protected Context setCtx() {
        return getContext();
    }

    @Override
    protected Class<? extends DialogAbstract> setCls() {
        return getClass();
    }

    @Override
    protected HandlerMain setHandlerMain() {
        return new ToastHandlerMain(getCtx(), getLogs()) {
            @Override
            protected void execute(Context context, int commandCode, String message) {
                if (MyApp.getInstance().getBuyList().size() <= 0) {

                    dialogCancel();
                } else {
                    Option option = optionMap.get(commandCode);

                    switch (option) {
                        case TOAST:
                            super.execute(context, commandCode, message);
                            break;
                        case COUNTDOWN_CANCEL:
                            cancelOnThreadCountdown();
                            break;
                        case SET_COUNTDOWN_TEXT:
                            setButtonCancelText(Integer.valueOf(message));
                            break;
                        case INVOICE_SUCCESSFUL:
                            MyApp.getInstance().getInvoiceData().setCarrier(message);
                            MyApp.getInstance().getReportFlowInfoData().setInvoiceInfo("carrier:" + MyApp.getInstance().getInvoiceData().getCarrier());
                            break;
                        case INVOICE_FAILED:
                            break;
                        case CHANGE_DISPATCH:
                            changeDispatch();
                            break;
                        case CHANGE_BUY:
                            changeBuy();
                            break;
                        case CHANGE_CHECKOUT:
                            changeCheckout();
                            break;
                    }
                }
            }
        };
    }

    private DialogCustomerIdentifierBinding binding;
    private CloseDialogOnThreadHandler closeDialogCountdown;
    private boolean openBarcode;
    private ReadBarCodeOnScheduler readBarCodeOnScheduler;

    public InvoiceCustomerIdentifierDialog(Context context, HandlerMain srcHandlerMain) {
        super(context, srcHandlerMain);
        openBarcode = true;
    }

    @Override
    protected void onCreate(Context context) {
        binding = DialogCustomerIdentifierBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.buttonFinish.setOnClickListener(v -> changeOk());
        binding.buttonDonation.setOnClickListener(v -> changeDonation());
        binding.buttonCancel.setOnClickListener(v -> changeBuy());

        closeDialogCountdown = new CloseDialogOnThreadHandler(getHandlerMain());
        closeDialogCountdown.start(40);

        readBarCodeOnScheduler = new ReadBarCodeOnScheduler(getHandlerMain());
        readBarCodeOnScheduler.start();

        binding.buttonR1.setOnClickListener(v -> {
            String text = binding.editTextNumber.getText().toString();
            if (text.length() > 0) { // ✅ 避免長度為 0 崩潰
                binding.editTextNumber.setText(text.substring(0, text.length() - 1));
                binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            }
            closeDialogCountdown.setCountdown(40);
        });

        binding.buttonC1.setOnClickListener(v -> {
            binding.editTextNumber.setText("");
            closeDialogCountdown.setCountdown(40);
        });

        binding.buttonR2.setOnClickListener(v -> {
            String text = binding.editTextPhone.getText().toString();
            if (text.length() > 0) { // ✅ 避免長度為 0 崩潰
                binding.editTextPhone.setText(text.substring(0, text.length() - 1));
                binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            }
            closeDialogCountdown.setCountdown(40);
        });

        binding.buttonC2.setOnClickListener(v -> {
            binding.editTextPhone.setText("");
            closeDialogCountdown.setCountdown(40);
        });

        binding.button10.setOnClickListener(v -> {
            String btnName = binding.button10.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button11.setOnClickListener(v -> {
            String btnName = binding.button11.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button12.setOnClickListener(v -> {
            String btnName = binding.button12.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button13.setOnClickListener(v -> {
            String btnName = binding.button13.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button14.setOnClickListener(v -> {
            String btnName = binding.button14.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button15.setOnClickListener(v -> {
            String btnName = binding.button15.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button16.setOnClickListener(v -> {
            String btnName = binding.button16.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button17.setOnClickListener(v -> {
            String btnName = binding.button17.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button18.setOnClickListener(v -> {
            String btnName = binding.button18.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button19.setOnClickListener(v -> {
            String btnName = binding.button19.getText().toString();
            String text = binding.editTextNumber.getText().toString();
            binding.editTextNumber.setText(text+btnName);
            binding.editTextNumber.setSelection(binding.editTextNumber.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button20.setOnClickListener(v -> {
            String btnName = binding.button20.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button21.setOnClickListener(v -> {
            String btnName = binding.button21.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button22.setOnClickListener(v -> {
            String btnName = binding.button22.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button23.setOnClickListener(v -> {
            String btnName = binding.button23.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button24.setOnClickListener(v -> {
            String btnName = binding.button24.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button25.setOnClickListener(v -> {
            String btnName = binding.button25.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button26.setOnClickListener(v -> {
            String btnName = binding.button26.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button27.setOnClickListener(v -> {
            String btnName = binding.button27.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button28.setOnClickListener(v -> {
            String btnName = binding.button28.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });

        binding.button29.setOnClickListener(v -> {
            String btnName = binding.button29.getText().toString();
            String text = binding.editTextPhone.getText().toString();
            binding.editTextPhone.setText(text+btnName);
            binding.editTextPhone.setSelection(binding.editTextPhone.getText().length());
            closeDialogCountdown.setCountdown(40);
        });
    }

    public void changeDispatch() {
        closeDialogCountdown.shutdown();
        DispatchDialog dispatchDialog = new DispatchDialog(getContext(), getSrcHandlerMain());
        dispatchDialog.show();
        openBarcode = false;
        cancel();
    }

    public void changeOk() {
        //----- 發票統編 ------
        String number = binding.editTextNumber.getText().toString();
        String phone = binding.editTextPhone.getText().toString();

        // 長度檢查
        if (number.length() < 8) {
            getHandlerMain().start(getClass().getSimpleName(), "統一編號長度不能少於 8 碼");
            return;
        }

        if (phone.length() < 10) {
            getHandlerMain().start(getClass().getSimpleName(), "電話號碼長度不能少於 10 碼");
            return;
        }
        MyApp.getInstance().getInvoiceData().setCustomerIdentifier(number);
        MyApp.getInstance().getInvoiceData().setPhone(phone);
        MyApp.getInstance().getReportFlowInfoData().setInvoiceInfo(
//                "customerIdentifier:" + MyApp.getInstance().getInvoiceData().getCustomerIdentifier()+
//                "phone:" + MyApp.getInstance().getInvoiceData().getPhone()
                MyApp.getInstance().getInvoiceData().getCustomerIdentifier()+ "-" +
                        MyApp.getInstance().getInvoiceData().getPhone()
        );
        changeCheckout();
    }

    public void changeDonation() {
        // 168001 OMG關懷社會愛心基金會
        MyApp.getInstance().getInvoiceData().setLoveCode("168001");
        MyApp.getInstance().getReportFlowInfoData().setInvoiceInfo(
//                "loveCode:" + MyApp.getInstance().getInvoiceData().getLoveCode()
                MyApp.getInstance().getInvoiceData().getLoveCode()
        );
        changeCheckout();
    }

    public void changeBuy() {
        closeDialogCountdown.shutdown();
        BuyDialog buyDialog = new BuyDialog(getContext(), getSrcHandlerMain());
        buyDialog.show();
        openBarcode = false;
        cancel();
    }

    public void changeCheckout() {
        closeDialogCountdown.shutdown();
        int flowType = MyApp.getInstance().getReportFlowInfoData().getFlowType();
        switch (flowType) {
            case 1:
                changeDialog(CheckoutNfcCardDialog.class);
                break;
            case 2:
                changeDialog(CheckoutNfcRechargeDialog.class);
                break;
            case 3:
                changeDialog(CheckoutEsunPayDialog.class);
                break;
            case 4:
                changeDialog(CheckoutNfcPhoneDialog.class);
                break;
            case 9:
                changeDialog(CashPayDialog.class);
                break;
            case 30:
                changeDialog(CheckoutTapPayDialog.class);
                break;
            case 70:
                changeDialog(CheckoutLinePayDialog.class);
                break;
        }
        openBarcode = false;
        cancel();
    }

    public void dialogCancel() {
        readBarCodeOnScheduler.setRun(false);
        closeDialogCountdown.shutdown();
        MyApp.getInstance().getBuyList().clear();
        openBarcode = false;
        cancel();
    }

    public void cancelOnThreadCountdown() {
        MyApp.getInstance().getBuyList().clear();
        openBarcode = false;
        cancel();
    }

    public void setButtonCancelText(long countdown) {
        binding.buttonCancel.setText(getContext().getString(R.string.return_to)+"("+countdown+")");//返回
    }

    public class ReadBarCodeOnScheduler extends HandlerMainScheduler {
        public ReadBarCodeOnScheduler(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
            try {
//                handlerMain.start(getClass().getSimpleName(), "40秒內可刷條碼");

                UsbDev usbDev = new UsbDev(DeviceType.QRCODE_SCANNER);
                byte[] buffer = new byte[20];
                usbDev.read(buffer, 100);
                for (int i=0; i<7; i++) {
                    if (isRun() && openBarcode) {
                        int size = usbDev.read(buffer, 5000);
                        if (size > 5) {
                            String barCodeString = new String(buffer, 0, size);
                            handlerMain.start(getClass().getSimpleName(), Option.INVOICE_SUCCESSFUL.getOption(), barCodeString);
                        }
                    }
                }
                usbDev.closePort();
            } catch (LogsUnsupportedOperationException | LogsIOException | LogsEmptyException e) {
                getLogs().warning(e);
            }
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    public static class CloseDialogOnThreadHandler extends HandlerMainCountdown {
        public CloseDialogOnThreadHandler(HandlerMain handlerMain) {
            super(handlerMain);
            handlerMain.start(getClass().getSimpleName(), CashPayDialog.Option.SET_COUNTDOWN_TEXT.getOption(), String.valueOf(getSrcCountdown()));
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void close(HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.COUNTDOWN_CANCEL.getOption(), "close dialog");
        }

        @Override
        protected void execute(long countdown, HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.SET_COUNTDOWN_TEXT.getOption(), String.valueOf(countdown));
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }
}
