package com.unibuy.smartdevice.ui.devs.vmc;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.unibuy.smartdevice.FragmentAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.R;
import com.unibuy.smartdevice.controller.DevController;
import com.unibuy.smartdevice.databinding.RecyclerVmcBuyListBinding;
import com.unibuy.smartdevice.devices.PortTools;
import com.unibuy.smartdevice.exception.Logs;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.ui.FontendActivity;
import com.unibuy.smartdevice.ui.dialog.DispatchDialog;
import com.unibuy.smartdevice.ui.recycler.RecyclerDialogBuyListAdpter;
import com.unibuy.smartdevice.ui.tools.ImageGlide;
import com.unibuy.smartdevice.ui.dialog.BuyDialog;
import com.unibuy.smartdevice.ui.dialog.MemberCardPickupDialog;
import com.unibuy.smartdevice.utils.LanguageHelper;

import java.util.List;

public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBuyListAdpter.ViewHolder> {
    private Logs logs;
    private Context context;
    private final List<SlotStructure> SlotList;
    private FragmentAbstract fragment;
    private boolean haveThings, doorError;
    private volatile boolean isCheckingSlot = false; // 點擊鎖：防止非同步檢查期間重複點擊

    public RecyclerVmcBuyListAdpter(FragmentAbstract fragment, List<SlotStructure> slotList) {
        this.logs = new Logs(this.getClass());
        this.context = fragment.getContext();
        this.SlotList = slotList;
        this.fragment = fragment;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        RecyclerVmcBuyListBinding binding;

        public ViewHolder(@NonNull RecyclerVmcBuyListBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 使用 ViewBinding 來綁定佈局
        RecyclerVmcBuyListBinding binding = RecyclerVmcBuyListBinding.inflate(LayoutInflater.from(parent.getContext()),
                parent, false);

        return new ViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // 讀取最後設定語言的設定
        LanguageHelper.applySavedLanguage(context);
        SlotStructure slot = SlotList.get(position);
        String urlString = slot.getProduct().getProductImg();
        try {
            new ImageGlide(context).fileload(urlString, holder.binding.imageProductPicture);
        } catch (LogsEmptyException e) {
            this.logs.warning(e);
        }
        holder.binding.textSlot.setText("貨道" + slot.getSlot());
        // 多國語的判斷
        String currentLang = LanguageHelper.getSavedLanguage(context);
        holder.binding.textProductName.setText(slot.getProduct().getProductName());
        switch (currentLang) {
            case "tw":
                holder.binding.textProductName.setText(slot.getProduct().getProductName());
                break;
            case "en":
                holder.binding.textProductName.setText(slot.getProduct().getProductNameEn());
                break;
            case "ja":
                holder.binding.textProductName.setText(slot.getProduct().getProductNameJp());
                break;
        }

        int machinePrice = slot.getProduct().getMachinePrice();
        int sellingPrice = slot.getProduct().getSellingPrice();
        int memberPrice = slot.getProduct().getMemberPrice();
        int slotUpperLimit = slot.getProduct().getSlotUpperLimit();
        int count = slot.getCount();
        boolean isLock = slot.isLock();

        int price = machinePrice > 0 ? machinePrice : sellingPrice;
        if (price > 0) {
            holder.binding.textPrice.setVisibility(View.VISIBLE);
            holder.binding.textPrice.setText("NT$ " + price);
        } else {
            holder.binding.textPrice.setVisibility(View.GONE);
        }

        // 綁定庫存數量顯示
        holder.binding.textStock.setText("庫存: " + count);

        holder.binding.mask.setVisibility(View.GONE);
        holder.binding.textMask.setText("");

        if (count <= 0) {
            holder.binding.mask.setVisibility(View.VISIBLE);
            holder.binding.textMask.setText("補貨中");// 已經售完
        }

        if (isLock) {
            holder.binding.mask.setVisibility(View.VISIBLE);
            holder.binding.textMask.setText("暫停販售");
        }

        if (count > 0 && !isLock) {
            holder.binding.imageProductPicture.setFocusable(false);
            holder.binding.imageProductPicture.setFocusableInTouchMode(false);
            holder.binding.imageProductPicture.setOnClickListener(new imageProductPictureOnClickListener(position));
        } else {
            holder.binding.imageProductPicture.setOnClickListener(null);
        }

        // devRunVMC(0);
    }

    @Override
    public int getItemCount() {
        return SlotList.size();
    }

    public void addSlotData(SlotStructure slotStructure) {
        SlotList.add(slotStructure);
        notifyItemInserted(SlotList.size() - 1);
    }

    public class imageProductPictureOnClickListener implements View.OnClickListener {
        private int position;

        public imageProductPictureOnClickListener(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            SlotStructure slotProduct = SlotList.get(position);
            if (slotProduct.isLock())
                return;
            if (MyApp.getInstance().isMachineBusy())
                return;
            // 防呆：正在檢查出貨口狀態時，不允許再次點擊
            if (isCheckingSlot)
                return;

            // ✅ 即時庫存檢查（防止 MQTT 更新後 UI 尚未刷新的時間差）
            try {
                SlotStructure liveSlot = MyApp.getInstance().getSlotData(slotProduct.getField(), slotProduct.getSlot());
                if (liveSlot != null && liveSlot.getCount() <= 0) {
                    logs.info("即時庫存檢查：商品已售罄 slot=" + slotProduct.getSlot());
                    android.widget.Toast.makeText(context, "商品已售罄", android.widget.Toast.LENGTH_SHORT).show();
                    // 觸發 UI 刷新讓商品顯示「補貨中」
                    fragment.getSrcHandlerMain().start(getClass().getSimpleName(),
                            VmcFragment.Option.SHIPPED_PRODUCT.getOption(), "refresh");
                    return;
                }
            } catch (LogsEmptyException e) {
                // 查詢失敗時不阻擋，讓原流程繼續
            }

            // 點選時即時檢查出貨口狀態（上鎖防止重複點擊）
            isCheckingSlot = true;
            checkSlotHaveProduct(slotProduct.getSlot(), 1, () -> {
                isCheckingSlot = false;
                BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(),
                        slotProduct.getProduct(), 1);
                MyApp.getInstance().getBuyList().add(buyProduct);
                fragment.getSrcHandlerMain().start(getClass().getSimpleName(),
                        FontendActivity.Option.STOP_COUNTDOWN.getOption(), "stop countdown");
                new MemberCardPickupDialog(context, fragment.getSrcHandlerMain()).show();
            });
        }
    }

    public void checkSlotHaveProduct(int slotnum, int slotcount, Runnable onSafe) {
        haveThings = false;
        doorError = false;

        java.util.concurrent.atomic.AtomicBoolean isHandled = new java.util.concurrent.atomic.AtomicBoolean(false);

        // 設定 3000ms 超時機制：如果機器沒反應，視為正常並繼續，避免程式卡住
        if (onSafe != null) {
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
                if (!isHandled.getAndSet(true)) {
                    logs.info("VMC Check Slot Timeout - Approving Safe (Timeout Safeguard)");
                    onSafe.run();
                }
            }, 3000);
        }

        logs.info("RecyclerDialogBuyListAdpter 111111111111111" + slotnum);
        logs.info("RecyclerDialogBuyListAdpter 222222222222222" + slotcount);
        MyApp.getInstance().getDevXinYuanController().addSendBuffer(
                MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlotPre(slotnum, slotcount));
        logs.info("RecyclerDialogBuyListAdpter 333333333333333");
        MyApp.getInstance().getDevXinYuanController()
                .addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlot(slotnum));
        logs.info("RecyclerDialogBuyListAdpter 444444444444444");
        // 使用較短的延遲（800ms）來加速讀取回覆，預設 2000ms 對 checkSlot 查詢來說太慢
        MyApp.getInstance().getDevXinYuanController()
                .getReadBufferByNow(new DevCheckSlotByVMC(fragment.getSrcHandlerMain(), onSafe, isHandled), 800);
    }

    public class DevCheckSlotByVMC extends DevController.ReadBufferOnScheduler {
        private Runnable onSafe;
        private java.util.concurrent.atomic.AtomicBoolean isHandled;

        public DevCheckSlotByVMC(HandlerMain handlerMain, Runnable onSafe, java.util.concurrent.atomic.AtomicBoolean isHandled) {
            super(handlerMain);
            this.onSafe = onSafe;
            this.isHandled = isHandled;
        }

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

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            // 每次檢查前先重置狀態旗標，修正 haveThings 狀態殘留 Bug
            doorError = false;
            haveThings = false;
            for (byte[] buffer : devController.getReadBufferByMax()) {
                if (buffer[0] == 0x02) {
                    getLogs().info("xxxxxxxxxxxxxxxxxxxxxxxxXinYuan Read:" + PortTools.showHex(buffer));
                    if (buffer[1] == 0x05) {
                        haveThings = true;
                        break;
                    } else if (buffer[1] == 0x06 || buffer[1] == 0x09) {
                        // 0x06：取貨口門沒關上
                        // 0x09：微波爐取貨口門關閉錯誤
                        getLogs().info("檢測到取貨口門未正常關閉，狀態碼=" + String.format("%02X", buffer[1]));
                        doorError = true;
                        break;
                    }
                }
            }

            if (haveThings) {
                if (isHandled.getAndSet(true)) return;
                // 使用主執行緒顯示 AlertDialog
                new Handler(Looper.getMainLooper()).post(() -> {
                    AlertDialog dialog = new AlertDialog.Builder(context)
                            .setTitle(R.string.abnormal_reminder)
                            .setMessage(R.string.there_is_something_at_the_pickup_port)
                            .setCancelable(false)
                            .setPositiveButton(R.string.i_knew, (d, which) -> {
                                d.dismiss();
                                isCheckingSlot = false;
                                handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
                                        "force close");
                            })
                            .create();

                    dialog.show();

                    // 放大提示文字
                    TextView messageView = dialog.findViewById(android.R.id.message);
                    if (messageView != null) {
                        messageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
                    }

                    // 加入 10 秒後自動觸發點擊確定
                    new Handler(Looper.getMainLooper()).postDelayed(() -> {
                        if (dialog.isShowing()) {
                            dialog.dismiss();
                            isCheckingSlot = false;
                            handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
                                    "force close");
                        }
                    }, 10_000); // 10 秒（10000 毫秒）
                });
            } else if (doorError) {
                if (isHandled.getAndSet(true)) return;
                // 取貨口門未關閉，提示使用者並阻止後續購買流程
                doorError = false;
                handlerMain.start("RecycleFlowerBuyListAdpter", "取貨口門未正常關閉，請先確認門已關好");
                // 使用主執行緒顯示 AlertDialog
                new Handler(Looper.getMainLooper()).post(() -> {
                    AlertDialog dialog = new AlertDialog.Builder(context)
                            .setTitle(R.string.abnormal_reminder)
                            .setMessage("取貨口門未正常關閉，請先確認門已關好。")
                            .setCancelable(false)
                            .setPositiveButton(R.string.i_knew, (d, which) -> {
                                d.dismiss();
                                isCheckingSlot = false;
                                handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
                                        "force close");
                            })
                            .create();

                    dialog.show();

                    // 放大提示文字
                    TextView messageView = dialog.findViewById(android.R.id.message);
                    if (messageView != null) {
                        messageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
                    }

                    // 加入 10 秒後自動觸發點擊確定
                    new Handler(Looper.getMainLooper()).postDelayed(() -> {
                        if (dialog.isShowing()) {
                            dialog.dismiss();
                            isCheckingSlot = false;
                            handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
                                    "force close");
                        }
                    }, 10_000); // 10 秒（10000 毫秒）
                });
            } else {
                // 狀態安全且無異常，執行購買回呼
                if (!isHandled.getAndSet(true)) {
                    if (onSafe != null) {
                        new Handler(Looper.getMainLooper()).post(onSafe);
                    }
                }
            }
        }
    }

    public class DevDetectSlotByVMC extends DevController.ReadBufferOnScheduler {
        private int position;

        public DevDetectSlotByVMC(HandlerMain handlerMain, int position) {
            super(handlerMain);
            this.position = position;
        }

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

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            for (byte[] buffer : devController.getReadBufferByMax()) {
                if (buffer[0] == 0x02 && buffer[1] == 0x01 || buffer[0] == 0x02 && buffer[1] == 0x02
                        || buffer[0] == 0x02 && buffer[1] == 0x04) {
                    SlotStructure slotProduct = SlotList.get(position);
                    BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(),
                            slotProduct.getProduct(), 1);
                    MyApp.getInstance().getBuyList().add(buyProduct);
                    handlerMain.start(getClass().getSimpleName(), FontendActivity.Option.STOP_COUNTDOWN.getOption(),
                            "stop countdown");
                    new BuyDialog(context, fragment.getSrcHandlerMain()).show();

                    return;
                }
            }

            handlerMain.start(getClass().getSimpleName(), "@貨道尚未準備好，三秒後再點選");// @貨道尚未準備好，三秒後再點選
        }
    }

    private void devRunVMC(int slot) {
        MyApp.getInstance().getDevXinYuanController()
                .getReadBufferByNow(new DevSelectSlotByMICO(fragment.getHandlerMain(), slot, false, false));
    }

    private int testCount;
    private int checkCount;
    private boolean isCMD;
    private boolean inTheMiddle;
    private boolean isSuccess;

    private void initDev() {
        testCount = 0;
        checkCount = 0;
        isCMD = false;
        inTheMiddle = false;
        isSuccess = false;
    }

    public class DevSelectSlotByMICO extends DevController.ReadBufferOnScheduler {
        private int slot;
        private boolean isMico;
        private boolean isHeading;

        public DevSelectSlotByMICO(HandlerMain handlerMain, int slot, boolean isMico, boolean isHeading) {
            super(handlerMain);

            this.slot = slot;
            this.isMico = isMico;
            this.isHeading = isHeading;
        }

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

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

        @Override
        public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
            for (byte[] buffer : devController.getReadBufferByMax()) {
                getLogs().info("DevSelectSlotByMICO:" + PortTools.showHex(buffer));

                if (buffer[0] == 0x02) {
                    isCMD = true;

                    if (buffer[1] == 0x01 ||
                            buffer[1] == 0x02 ||
                            buffer[1] == 0x04) {
                        isSuccess = true;
                        break;
                    }
                }

                if (buffer[0] == 0x03 && buffer[1] == 0x03) {
                    isCMD = true;
                }
            }

            getLogs().info("vmc isCMD:" + isCMD + " isSuccess:" + isSuccess);

            if (isCMD) {
                if (isSuccess) {
                    initDev();
                    // getSrcHandlerMain().start(getClass().getSimpleName(),
                    // DispatchDialog.Option.SET_MESSAGE_TEXT.getOption(), "檢測貨道可出貨");
                    // if (isMico) {
                    // MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
                    // DevMicoInfo65ByMICO(getHandlerMain(), slot, isHeading));
                    // MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMicoHeating(isHeading));
                    // } else {
                    // MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
                    // DevGetProductByMICO(getHandlerMain(), slot));
                    // MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().getProduct(slot));
                    // }
                } else {
                    if (checkCount > 15) {
                        getSrcHandlerMain().start(getClass().getSimpleName(),
                                DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "請檢查商品有無取出再確認取貨");
                    } else {
                        // getSrcHandlerMain().start(getClass().getSimpleName(),
                        // Option.SET_MESSAGE_TEXT.getOption(), "檢查中");
                        // MyApp.getInstance().getDevXinYuanController().getReadBuffer(new
                        // DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
                        checkCount++;
                    }
                }
            } else {
                if (testCount > 15) {
                    // getSrcHandlerMain().start(getClass().getSimpleName(),
                    // DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "下位機無回應 請等3秒後再重試");
                } else {
                    // MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
                    // DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
                    // MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().selectSlot(slot));
                    testCount++;
                }
            }
        }
    }
}
