package com.unibuy.smartdevice.ui.dialog;

import android.content.Context;
import android.view.View;

import com.unibuy.smartdevice.DialogAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.R;
import com.unibuy.smartdevice.controller.DevController;
import com.unibuy.smartdevice.controller.DevXinYuanController;
import com.unibuy.smartdevice.databinding.DialogCheckoutCashBinding;
import com.unibuy.smartdevice.devices.DevXinYuan;
import com.unibuy.smartdevice.devices.PortTools;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsParseException;
import com.unibuy.smartdevice.exception.LogsSettingEmptyException;
import com.unibuy.smartdevice.external.HttpAPI;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.InvoiceItemStructure;
import com.unibuy.smartdevice.structure.ReportFreeGiftCodeStructure;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.HandlerMainCountdown;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.ui.FontendActivity;

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

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

public class CheckoutCashDialog extends DialogAbstract {
    public enum Option {
        TOAST(0),
        COUNTDOWN_CANCEL(1),
        SET_COUNTDOWN_TEXT(2),
        OPEN_CASH_IN(3),
        CLOSE_CASH_IN(4),
        CASH_IN(5),
        CHANGE_DISPATCH(6),
        CHANGE_BUY(7),
        REPORT_FLOW(8),
        POST_INVOICE(9),
        REPORT_INVOICE(10),
        GET_CHANGE(11),
        ;

        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);
                    getLogs().info("Option " + option.getOption() + ":" + option.name());
                    switch (option) {
                        case TOAST:
                            super.execute(context, commandCode, message);
                            break;
                        case COUNTDOWN_CANCEL:
                            cancelOnThreadCountdown();
                            break;
                        case SET_COUNTDOWN_TEXT:
                            try {
                                setButtonCancelText(Integer.valueOf                                                                                                                                        (message));
                            } catch (NumberFormatException e) {
                                throw new RuntimeException(e);
                            }
                            break;
                        case OPEN_CASH_IN:
                            binding.textGetMoney.setText(message);
                            binding.mark.setVisibility(View.GONE);
                            cashIn();
                            break;
                        case CASH_IN:
                            binding.textGetMoney.setText(message);
                            closeDialogCountdown.setCountdown(40);
                            break;
                        case GET_CHANGE:
                            if (MyApp.getInstance().getReportFlowInfoData().getFlowStatusType() == 0) {
                                if (getMoney > 0) {
                                    binding.textGetMoney.setText(getContext().getString(R.string.refund) + "" + String.valueOf(getMoney));
                                    giveChange(getMoney);
                                } else {
                                    binding.textGetMoney.setText(message);
                                }
                            }
                            closeDialogCountdown.setCountdown(10);
                            closeMoneyType();
                            break;
                        case CLOSE_CASH_IN:
                            if (isCloseCashIn) {
                                binding.textGetMoney.setText(message);

                                if (MyApp.getInstance().getReportFlowInfoData().getFlowStatusType() == 0) {
                                    start(getSrcClassName(), Option.CHANGE_BUY.getOption(), "change buy");
                                } else {
                                    try {
                                        httpAPI.reportFlowInfo(MyApp.getInstance().getReportFlowInfoData());
                                    } catch (LogsSettingEmptyException | LogsParseException e) {
                                        getLogs().warning(e);
                                    }
                                }
                                isCloseCashIn = false;
                            }
                            break;
                        case CHANGE_DISPATCH:
                            changeDispatch();
                            break;
                        case CHANGE_BUY:
                            changeBuy();
                            break;
                        case REPORT_FLOW:
                            getLogs().info(MyApp.getInstance().getReportFlowInfoData().toString());

                            if (MyApp.getInstance().getReportFlowInfoData().getFlowStatusType() == 0) {
                                start(getSrcClassName(), "@"+getContext().getString(R.string.transaction_failure));
                                start(getSrcClassName(), Option.CHANGE_BUY.getOption(), "change buy");
                            } else {
                                if (MyApp.getInstance().getReportFlowInfoData().getInvoiceInfo().isEmpty()) {
                                    start(getSrcClassName(), Option.CHANGE_DISPATCH.getOption(), "change dispatch");
                                } else {
                                    start(getSrcClassName(), Option.POST_INVOICE.getOption(), "post invoice");
                                }
                            }

                            break;
                        case POST_INVOICE:
                            try {
                                httpAPI.postInvoiceByGreen(MyApp.getInstance().getPostInvoiceByGreenData());
                            } catch (LogsSettingEmptyException | LogsParseException e) {
                                getLogs().warning(e);
                            }
                            start(getSrcClassName(), CheckoutEsunPayDialog.Option.CHANGE_DISPATCH.getOption(), "change dispatch");
                            break;
                        case REPORT_INVOICE:
                            start(getSrcClassName(), Option.CHANGE_DISPATCH.getOption(), "change dispatch");
                            break;
                    }
                }
            }
        };
    }

    private DialogCheckoutCashBinding binding;
    private CloseDialogOnThreadHandler closeDialogCountdown;
    private boolean isRun;
    private boolean isGiveChange;
    private boolean isCloseCashIn;
    private boolean isChangeDispatch;
    private int vmc29MoneySwitch;
    private int getTotalPrice;
    private int getMoney;
    private HttpAPI httpAPI;

    public CheckoutCashDialog(Context context, HandlerMain srcHandlerMain) {
        super(context, srcHandlerMain);
    }

    @Override
    protected void onCreate(Context context) {
        binding = DialogCheckoutCashBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        this.isRun = true;
        this.vmc29MoneySwitch = 0;
        this.isGiveChange = true;
        this.isCloseCashIn = true;
        this.isChangeDispatch = true;
        this.httpAPI = new HttpAPI(getHandlerMain());

        binding.buttonChange.setOnClickListener(v -> changeBuy());
        binding.buttonCancel.setOnClickListener(v -> dialogCancel());

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

        getTotalPrice = getTotalPrice();
        binding.textPrice.setText(String.valueOf(getTotalPrice));
        binding.textGetMoney.setText(getContext().getString(R.string.waiting_opening));//等待開啟
        binding.mark.setVisibility(View.VISIBLE);

        if (MyApp.getInstance().getCashSetStructure().isBillF1000()) {
            binding.imageCheckoutBill1000.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutBill1000.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isBillE500()) {
            binding.imageCheckoutBill500.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutBill500.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isBillD100()) {
            binding.imageCheckoutBill100.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutBill100.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isCoinF50()) {
            binding.imageCheckoutCoin50.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutCoin50.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isCoinE10()) {
            binding.imageCheckoutCoin10.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutCoin10.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isCoinD5()) {
            binding.imageCheckoutCoin5.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutCoin5.setVisibility(View.GONE);
        }
        if (MyApp.getInstance().getCashSetStructure().isCoinC1()) {
            binding.imageCheckoutCoin1.setVisibility(View.VISIBLE);
        } else {
            binding.imageCheckoutCoin1.setVisibility(View.GONE);
        }

        MyApp.getInstance().getReportFlowInfoData().setFlowSendInfo("");
        MyApp.getInstance().getReportFlowInfoData().setFlowRequestInfo("");
        MyApp.getInstance().getReportFlowInfoData().setProductId(MyApp.getInstance().getBuyList().get(0).getProduct().getProductID());
        MyApp.getInstance().getReportFlowInfoData().setTotalPrice(getTotalPrice());
        MyApp.getInstance().getReportFlowInfoData().setFlowStatusType(0);
        JSONArray jsonArray = new JSONArray();
        try {
            for (BuyStructure buyData : MyApp.getInstance().getBuyList()) {
                JSONObject productData = new JSONObject();
                productData.put("pid", buyData.getProduct().getProductID());
                productData.put("amount", String.valueOf(buyData.getProduct().getRealPrice()));
                productData.put("num", String.valueOf(buyData.getCount()));
                jsonArray.put(productData);

                InvoiceItemStructure invoiceItem = new InvoiceItemStructure("", "", 0, "件", 0, 0);
                invoiceItem.setItemSeq(buyData.getProduct().getProductID());
                invoiceItem.setItemName(buyData.getProduct().getProductName());
                invoiceItem.setItemCount(buyData.getCount());
                invoiceItem.setItemPrice(buyData.getProduct().getRealPrice());
                invoiceItem.setItemAmount(buyData.getFullPrice());
                try {
                    SlotField slotField = SlotField.getSlotField(buyData.getField());
                    switch (slotField) {
                        case VMC:
                            invoiceItem.setItemWord("件");
                            break;
                        case ELECTRIC:
                            invoiceItem.setItemWord("時");
                            break;
                    }
                } catch (LogsEmptyException e) {
                    invoiceItem.setItemWord("件");
                }
                MyApp.getInstance().getInvoiceItems().add(invoiceItem);
            }
            MyApp.getInstance().getPostInvoiceByGreenData().setInvoiceItem(MyApp.getInstance().getInvoiceItems());
            MyApp.getInstance().getPostInvoiceByGreenData().setInvoiceData(MyApp.getInstance().getInvoiceData());
            MyApp.getInstance().getPostInvoiceByGreenData().setTotalPrice(getTotalPrice());
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        MyApp.getInstance().getReportFlowInfoData().setShoppingCartInfoByJsonArray(jsonArray);

        this.vmc29MoneySwitch = 0;
        getLogs().debug("設定紙幣：");
        MyApp.getInstance().getDevXinYuanController().clearSendBuffers();
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().inComeByIPC((byte) 0x08, 9999));
        MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new OpenCashInByDevXinYuan(getHandlerMain()), 1000);
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x00, MyApp.getInstance().getCashSetStructure().getByteByBill1(), MyApp.getInstance().getCashSetStructure().getByteByBill2()));
    }

    public class OpenCashInByDevXinYuan extends DevController.ReadBufferOnScheduler {
        public OpenCashInByDevXinYuan(HandlerMain handlerMain) {
            super(handlerMain);
        }

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            if (!isRun) return;

            for (byte[] buffer: devController.getReadBufferByMax()) {
                if (buffer == null || buffer.length == 0)
                    continue;

                getLogs().info("OpenCashInByDevXinYuan:"+PortTools.showHex(buffer));

                Byte key = Byte.valueOf(buffer[0]);

                if (!DevXinYuanController.vmcMap.containsKey(key))
                    continue;

                DevXinYuan.VMC vmc = DevXinYuanController.vmcMap.get(key);

                if (vmc == null) continue;

                switch (vmc) {
                    case VMC_29_MONEY_SWITCH:
                        if (buffer.length >= 2 && buffer[1] == 0x00) {
                            if (vmc29MoneySwitch == 0) {
                                vmc29MoneySwitch = 1;
                                setRun(true);
                                getLogs().debug("設定硬幣：");
                                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new OpenCashInByDevXinYuan(handlerMain), 1000);
                                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x01, MyApp.getInstance().getCashSetStructure().getByteByCoin1(), MyApp.getInstance().getCashSetStructure().getByteByCoin2()));
                                return;
                            } else if (vmc29MoneySwitch == 1) {
                                vmc29MoneySwitch = 0;
                                isCloseCashIn = true;
                                handlerMain.start(getClass().getSimpleName(), Option.OPEN_CASH_IN.getOption(), getCtx().getString(R.string.insert_coin));//請投幣
                                return;
                            }
                        }
                        break;
                }
            }

            if (vmc29MoneySwitch == 0) {
                getLogs().debug("重設紙幣：");
                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new OpenCashInByDevXinYuan(handlerMain), 1000);
                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x00, MyApp.getInstance().getCashSetStructure().getByteByBill1(), MyApp.getInstance().getCashSetStructure().getByteByBill2()));
            } else if (vmc29MoneySwitch == 1) {
                getLogs().debug("重設硬幣：");
                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new OpenCashInByDevXinYuan(handlerMain), 1000);
                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x01, MyApp.getInstance().getCashSetStructure().getByteByCoin1(), MyApp.getInstance().getCashSetStructure().getByteByCoin2()));
            }
        }

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

    public void cashIn() {
        MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CashInByDevXinYuan(getHandlerMain()), 1000);
    }

    public class CashInByDevXinYuan extends DevController.ReadBufferOnScheduler {

        public CashInByDevXinYuan(HandlerMain handlerMain) {
            super(handlerMain);
        }

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            if (!isRun) return;

            for (byte[] buffer: devController.getReadBufferByMax()) {
                if (buffer == null || buffer.length == 0)
                    continue;

                getLogs().info("CashInByDevXinYuan:"+PortTools.showHex(buffer));

                Byte key = Byte.valueOf(buffer[0]);

                if (!DevXinYuanController.vmcMap.containsKey(key))
                    continue;

                DevXinYuan.VMC vmc = DevXinYuanController.vmcMap.get(key);

                if (vmc == null) continue;

                switch (vmc) {
                    case VMC_23_NOW_GET_TOTAL:
                        if (buffer.length >= 4 && buffer[1] == 0x00) {
                            getMoney = PortTools.byte8ToInt(buffer[2], buffer[3]);
                            getLogs().debug("getMoney:" + getMoney);
                            if (getMoney > 0) {
                                int remaining = getMoney - getTotalPrice;
                                if (remaining >= 0) {
                                    MyApp.getInstance().getReportFlowInfoData().setFlowStatusType(1);

                                    if (remaining > 0) {
                                        giveChange(remaining);
                                        MyApp.getInstance().getReportFlowInfoData().setGiveChange(remaining);

                                        getMoney = getTotalPrice;

                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException e) {
                                            throw new RuntimeException(e);
                                        }

                                        handlerMain.start(getClass().getSimpleName(), Option.GET_CHANGE.getOption(),  getCtx().getString(R.string.change)+":" + remaining);//找零
                                    } else {
                                        handlerMain.start(getClass().getSimpleName(), Option.GET_CHANGE.getOption(), getCtx().getString(R.string.completed));//已完成
                                    }

                                    MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().inComeByIPC((byte) 0x08, getMoney));
                                    //送出資料
                                    getMoney = 0;

                                    return;
                                } else {
                                    handlerMain.start(getClass().getSimpleName(), Option.CASH_IN.getOption(), String.valueOf(getMoney));
                                }
                            }
                        }
                }
            }

            MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CashInByDevXinYuan(handlerMain), 1000);
        }

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

    public int getTotalPrice() {
        int totalPrice = 0;
        if (MyApp.getInstance().getBuyList().size() == 0) return totalPrice;
        for(BuyStructure buy: MyApp.getInstance().getBuyList()) {
            if (!buy.isFreeGift()) totalPrice += buy.getFullPrice();
        }
        if (MyApp.getInstance().getReportFreeGiftCodeStructure() != null) {
            switch (MyApp.getInstance().getReportFreeGiftCodeStructure().getMode()) {
                case 0:
                    break;
                case 1:
                    totalPrice = totalPrice - MyApp.getInstance().getReportFreeGiftCodeStructure().getDiscountAmount();
                    break;
                case 2:
                    totalPrice = (int) (totalPrice * MyApp.getInstance().getReportFreeGiftCodeStructure().getDiscountPercentage());
                    break;
            }
        }
        if (totalPrice == 0) totalPrice = 1;
        return totalPrice;
    }

    public void closeMoneyType() {
        vmc29MoneySwitch = 0;
        getLogs().debug("關閉紙幣：");
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().inComeByIPC((byte) 0x08, 9999));
        MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CloseCashInByDevXinYuan(getHandlerMain()), 3000);
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x00, (byte)0x00, (byte)0x00));
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x01, (byte)0x00, (byte)0x00));
    }

    public class CloseCashInByDevXinYuan extends DevController.ReadBufferOnScheduler {

        public CloseCashInByDevXinYuan(HandlerMain handlerMain) {
            super(handlerMain);
        }

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            if (!isRun) return;

            for (byte[] buffer: devController.getReadBufferByMax()) {
                if (buffer == null || buffer.length == 0)
                    continue;

                getLogs().info("CloseCashInByDevXinYuan:"+PortTools.showHex(buffer));

                Byte key = Byte.valueOf(buffer[0]);

                if (!DevXinYuanController.vmcMap.containsKey(key))
                    continue;

                DevXinYuan.VMC vmc = DevXinYuanController.vmcMap.get(key);

                if (vmc == null) continue;

                switch (vmc) {
                    case VMC_29_MONEY_SWITCH:
                        if (buffer.length >= 2 && buffer[1] == 0x00) {
                            if (vmc29MoneySwitch == 0) {
                                vmc29MoneySwitch = 1;
                                getLogs().debug("關閉硬幣：");
                                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CloseCashInByDevXinYuan(handlerMain), 1000);
                                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x01, (byte) 0x00, (byte) 0x00));
                                return;
                            } else if (vmc29MoneySwitch == 1) {
                                vmc29MoneySwitch = 0;
                                handlerMain.start(getClass().getSimpleName(), Option.CLOSE_CASH_IN.getOption(), getCtx().getString(R.string.close_cash_slot));//關閉現金口
                                return;
                            }
                        }
                }
            }

            if (vmc29MoneySwitch == 0) {
                getLogs().debug("重關紙幣：");
                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CloseCashInByDevXinYuan(handlerMain), 2000);
                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x00, (byte)0x00, (byte)0x00));
            } else if (vmc29MoneySwitch == 1) {
                getLogs().debug("重關硬幣：");
                MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new CloseCashInByDevXinYuan(handlerMain), 2000);
                MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMoneyType((byte) 0x01, (byte)0x00, (byte)0x00));
            }
        }

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

    public void giveChange(int number) {
        if (!isGiveChange) return;

        if (number > 0) {
            MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new GiveChangeInByDevXinYuan(getHandlerMain()), 1000);
            MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().giveChange(number));
            isGiveChange = false;
        }
    }

    public class GiveChangeInByDevXinYuan extends DevController.ReadBufferOnScheduler {

        public GiveChangeInByDevXinYuan(HandlerMain handlerMain) {
            super(handlerMain);
        }

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            for (byte[] buffer: devController.getReadBufferByMax()) {
                if (buffer == null || buffer.length == 0)
                    continue;

                getLogs().info("GiveChangeInByDevXinYuan:"+PortTools.showHex(buffer));

                Byte key = Byte.valueOf(buffer[0]);

                if (!DevXinYuanController.vmcMap.containsKey(key))
                    continue;

                DevXinYuan.VMC vmc = DevXinYuanController.vmcMap.get(key);

                if (vmc == null) continue;

                switch (vmc) {
                    case VMC_26_GIVE_CHANGE:
                        handlerMain.start(getClass().getSimpleName(), "get 26");
                        return;
                }
            }
        }

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

    public void changeDispatch() {
        if (isChangeDispatch){
            isRun = false;
            isChangeDispatch = false;
            closeDialogCountdown.shutdown();
            changeDialog(DispatchDialog.class);
        }
    }

    public void changeBuy() {
        isRun = false;
        if (getMoney > 0) {
            giveChange(getMoney);
        }
        closeMoneyType();
        closeDialogCountdown.shutdown();
        changeDialog(BuyDialog.class);
    }

    public void dialogCancel() {
        MyApp.getInstance().setReportFreeGiftCodeStructure(new ReportFreeGiftCodeStructure("", 0, "", 0, 0, ""));
        getSrcHandlerMain().start(getClass().getSimpleName(), FontendActivity.Option.STOP_COUNTDOWN.getOption(), "");
        isRun = false;
        if (getMoney > 0) {
            giveChange(getMoney);
        }
        closeMoneyType();
        closeDialogCountdown.shutdown();
        MyApp.getInstance().getBuyList().clear();
        cancel();
    }

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

    public void setButtonCancelText(long countdown) {
        binding.buttonCancel.setText("取消("+countdown+")");
    }

    public static class CloseDialogOnThreadHandler extends HandlerMainCountdown {
        boolean isCloseMoney = false;

        public CloseDialogOnThreadHandler(HandlerMain handlerMain) {
            super(handlerMain);
            isCloseMoney = false;
        }

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

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

        @Override
        protected void execute(long countdown, HandlerMain handlerMain) {
            if (countdown >= 5) {
                handlerMain.start(getClass().getSimpleName(), Option.SET_COUNTDOWN_TEXT.getOption(), String.valueOf(countdown));
            } else {
                if (!isCloseMoney) {
                    handlerMain.start(getClass().getSimpleName(), Option.GET_CHANGE.getOption(), "關閉中");
                }
            }
        }

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