package com.unibuy.smartdevice.ui;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TableRow;
import android.widget.TextView;

import com.unibuy.smartdevice.AppCompatActivityAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.databinding.ActivitySystemSetBinding;
import com.unibuy.smartdevice.external.StarCloudAPI;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.ToastHandlerMain;

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

/**
 * 主控台「系統設定」：呈現雲端 B014 下發的開關設定。
 * 系統方（identity=system）可編輯並按「儲存」回寫雲端（B016）；其他身分唯讀。
 */
public class SystemSetActivity extends AppCompatActivityAbstract {
    private ActivitySystemSetBinding binding;
    private boolean isSystem;

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

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

    @Override
    protected HandlerMain setHandlerMain() {
        return new ToastHandlerMain(getCtx(), getLogs());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivitySystemSetBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        isSystem = MyApp.getInstance().isSystemIdentity();

        applyShoppingModeView();
        updateCheckBoxes();
        applyRolePermission();
        applyPortProfileView();

        binding.buttonBack.setOnClickListener(v -> finish());
        binding.buttonSave.setOnClickListener(v -> onSaveClicked());
        binding.buttonPortProfile.setOnClickListener(v -> showPortProfileDialog());
    }

    /**
     * 串口方案（本機硬體設定，不回寫雲端）：顯示目前方案並提供切換。因應不同 IPC 主板的
     * 下位機(主櫃 XinYuan)/刷卡機(NFCPay)串口位置不一致——舊版本 ttyS1/ttyS2、星科技 ttyS7/ttyS6。
     */
    private void applyPortProfileView() {
        String profile = com.unibuy.smartdevice.devices.PortProfile.getProfile(getCtx());
        binding.textViewPortProfile.setText(
                com.unibuy.smartdevice.devices.PortProfile.displayName(profile));
    }

    /** 顯示串口方案選單；選到不同方案時持久化並提示重啟套用（串口於 app 啟動時綁定）。 */
    private void showPortProfileDialog() {
        final String current = com.unibuy.smartdevice.devices.PortProfile.getProfile(getCtx());
        final String[] values = {
                com.unibuy.smartdevice.devices.PortProfile.LEGACY,
                com.unibuy.smartdevice.devices.PortProfile.STARTECH
        };
        final String[] labels = {
                "舊版本（下位機 ttyS1／刷卡機 ttyS2）",
                "星科技（下位機 ttyS7／刷卡機 ttyS6）"
        };
        int checked = com.unibuy.smartdevice.devices.PortProfile.STARTECH.equals(current) ? 1 : 0;

        new android.app.AlertDialog.Builder(this)
                .setTitle("選擇串口方案（本機）")
                .setSingleChoiceItems(labels, checked, null)
                .setPositiveButton("套用", (dialog, which) -> {
                    int pos = ((android.app.AlertDialog) dialog).getListView().getCheckedItemPosition();
                    if (pos < 0) return;
                    String selected = values[pos];
                    if (selected.equals(current)) {
                        android.widget.Toast.makeText(getCtx(), "方案未變更", android.widget.Toast.LENGTH_SHORT).show();
                        return;
                    }
                    com.unibuy.smartdevice.devices.PortProfile.setProfile(getApplicationContext(), selected);
                    applyPortProfileView();
                    getLogs().info("[串口方案] 切換為 " + selected + "，將重啟 app 套用");
                    confirmRestartForPortProfile(selected);
                })
                .setNegativeButton("取消", null)
                .show();
    }

    /** 切換方案後需重啟 app 才會以新串口開啟；提示並重啟。 */
    private void confirmRestartForPortProfile(String selected) {
        new android.app.AlertDialog.Builder(this)
                .setTitle("需重啟套用")
                .setMessage("已設定為「" + com.unibuy.smartdevice.devices.PortProfile.displayName(selected)
                        + "」。\n\n串口於 app 啟動時綁定，需重啟 app 才會以新串口連線。是否立即重啟？")
                .setCancelable(false)
                .setPositiveButton("立即重啟", (d, w) -> restartApp())
                .setNegativeButton("稍後重啟", null)
                .show();
    }

    /** 清空 Task 重新啟動首頁並結束本行程，重新以新串口方案接管硬體。 */
    private void restartApp() {
        new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
            android.content.Intent intent = new android.content.Intent(
                    getApplicationContext(), com.unibuy.smartdevice.AppEntry.initialActivity());
            intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK
                    | android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
                    | android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            finishAffinity();
            android.os.Process.killProcess(android.os.Process.myPid());
        });
    }

    /**
     * 購物方式（雲端 B014 ShoppingMode，機台唯讀）：顯示中文名稱，並只在 basic（基礎版）
     * 時顯示其下的可設定項；員工卡／取貨單模式整段隱藏（流程與硬體由雲端固定，現場不可調）。
     */
    private void applyShoppingModeView() {
        String mode = MyApp.getInstance().getShoppingMode();
        String label;
        switch (mode == null ? "" : mode) {
            case "employee_card":
                label = "員工卡";
                break;
            case "pickup_sheet":
                label = "取貨單";
                break;
            case "basic":
            default:
                label = "基礎版";
                break;
        }
        binding.textViewShoppingMode.setText("購物方式：" + label);
        binding.layoutBasicOnlySettings.setVisibility("basic".equals(mode) ? View.VISIBLE : View.GONE);
        applyPharmacyPickupView(mode);
    }

    /**
     * 領藥單功能狀態：僅「取貨單(pickup_sheet)」模式才顯示，狀態取自雲端 B014 下發的
     * FunctionSet.PharmacyPickup（機台唯讀）。啟用→綠色「啟用中」、未啟用→橘色「未啟用」。
     */
    private void applyPharmacyPickupView(String mode) {
        if (!"pickup_sheet".equals(mode)) {
            binding.textViewPharmacyPickup.setVisibility(View.GONE);
            return;
        }
        boolean enabled = MyApp.getInstance().getDevSet().isPharmacyPickup();
        binding.textViewPharmacyPickup.setVisibility(View.VISIBLE);
        binding.textViewPharmacyPickup.setText("領藥單功能：" + (enabled ? "啟用中" : "未啟用"));
        binding.textViewPharmacyPickup.setTextColor(androidx.core.content.ContextCompat.getColor(
                getCtx(), enabled ? com.unibuy.smartdevice.R.color.success : com.unibuy.smartdevice.R.color.warning));
    }

    /** 將記憶體中的設定值套到各 CheckBox。 */
    private void updateCheckBoxes() {
        binding.checkboxShoppingCar.setChecked(MyApp.getInstance().getDevSet().isShoppingCar());
        binding.checkboxInvoice.setChecked(MyApp.getInstance().getDevSet().isInvoice());
        binding.cardDevShoppingCar.setVisibility(MyApp.getInstance().getDevSet().isShoppingCar() ? View.VISIBLE : View.GONE);
        binding.cardDevInvoice.setVisibility(MyApp.getInstance().getDevSet().isInvoice() ? View.VISIBLE : View.GONE);

        boolean isNfcPayEnabled = MyApp.getInstance().getDevSet().isDevNFCPay();
        
        if (isNfcPayEnabled) {
            binding.textViewNFCStatusHint.setText("啟用中");
            binding.textViewNFCStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.success));
            binding.gridLayoutNFCPayOptions.setVisibility(View.VISIBLE);
        } else {
            binding.textViewNFCStatusHint.setText("功能未啟用");
            binding.textViewNFCStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.warning));
            binding.gridLayoutNFCPayOptions.setVisibility(View.GONE);
        }

        binding.cardDevCreditCard.setVisibility(MyApp.getInstance().getDevSet().isDevCreditCard() ? View.VISIBLE : View.GONE);
        binding.cardDevMobilePay.setVisibility(MyApp.getInstance().getDevSet().isDevMobilePay() ? View.VISIBLE : View.GONE);
        binding.cardDevCardPay.setVisibility(MyApp.getInstance().getDevSet().isDevCardPay() ? View.VISIBLE : View.GONE);

        boolean isScanPayEnabled = MyApp.getInstance().getDevSet().isDevScanPay();
        binding.checkboxDevScanPay.setChecked(isScanPayEnabled);
        
        if (isScanPayEnabled) {
            binding.textViewScanStatusHint.setText("啟用中");
            binding.textViewScanStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.success));
            binding.layoutScanPayOptions.setVisibility(View.VISIBLE);
        } else {
            binding.textViewScanStatusHint.setText("功能未啟用");
            binding.textViewScanStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.warning));
            binding.layoutScanPayOptions.setVisibility(View.GONE);
        }

        boolean isEsunEnabled = MyApp.getInstance().getDevSet().isDevEsunPay();
        binding.checkboxDevEsunPay.setChecked(isEsunEnabled);
        int esunVisibility = isEsunEnabled ? View.VISIBLE : View.GONE;
        binding.cardDevEsunPay.setVisibility(esunVisibility);
        binding.cardDevEsunSubTaiwanPay.setVisibility(esunVisibility);

        boolean isTapPayEnabled = MyApp.getInstance().getDevSet().isDevTapPay();
        binding.checkboxDevTapPay.setChecked(isTapPayEnabled);
        binding.cardDevTapPay.setVisibility(isTapPayEnabled ? View.VISIBLE : View.GONE);
        
        binding.checkboxDevTapPay30.setChecked(MyApp.getInstance().getDevSet().isTapPay30());
        binding.checkboxDevTapPay31.setChecked(MyApp.getInstance().getDevSet().isTapPay31());
        binding.checkboxDevTapPay32.setChecked(MyApp.getInstance().getDevSet().isTapPay32());
        binding.checkboxDevTapPay33.setChecked(MyApp.getInstance().getDevSet().isTapPay33());
        binding.checkboxDevTapPay34.setChecked(MyApp.getInstance().getDevSet().isTapPay34());

        binding.cardDevTapPay30.setVisibility(isTapPayEnabled && MyApp.getInstance().getDevSet().isTapPay30() ? View.VISIBLE : View.GONE);
        binding.cardDevTapPay31.setVisibility(isTapPayEnabled && MyApp.getInstance().getDevSet().isTapPay31() ? View.VISIBLE : View.GONE);
        binding.cardDevTapPay32.setVisibility(isTapPayEnabled && MyApp.getInstance().getDevSet().isTapPay32() ? View.VISIBLE : View.GONE);
        binding.cardDevTapPay33.setVisibility(isTapPayEnabled && MyApp.getInstance().getDevSet().isTapPay33() ? View.VISIBLE : View.GONE);
        binding.cardDevTapPay34.setVisibility(isTapPayEnabled && MyApp.getInstance().getDevSet().isTapPay34() ? View.VISIBLE : View.GONE);

        boolean isLinePayEnabled = MyApp.getInstance().getDevSet().isDevLinePay();
        binding.checkboxDevLinePay.setChecked(isLinePayEnabled);
        binding.cardDevLinePay.setVisibility(isLinePayEnabled ? View.VISIBLE : View.GONE);
        binding.cardDevLineSubLinePay.setVisibility(isLinePayEnabled ? View.VISIBLE : View.GONE);

        boolean isCashEnabled = MyApp.getInstance().getDevSet().isDevCash();
        binding.checkboxDevCash.setChecked(isCashEnabled);
        
        if (isCashEnabled) {
            binding.textViewCashStatusHint.setText("啟用中");
            binding.textViewCashStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.success));
            binding.layoutCashPayOptions.setVisibility(View.VISIBLE);
        } else {
            binding.textViewCashStatusHint.setText("功能未啟用");
            binding.textViewCashStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.warning));
            binding.layoutCashPayOptions.setVisibility(View.GONE);
        }

        binding.checkboxDevBillF.setChecked(MyApp.getInstance().getCashSetStructure().isBillF1000());
        binding.checkboxDevBillE.setChecked(MyApp.getInstance().getCashSetStructure().isBillE500());
        binding.checkboxDevBillD.setChecked(MyApp.getInstance().getCashSetStructure().isBillD100());
        binding.checkboxDevCoinF.setChecked(MyApp.getInstance().getCashSetStructure().isCoinF50());
        binding.checkboxDevCoinE.setChecked(MyApp.getInstance().getCashSetStructure().isCoinE10());
        binding.checkboxDevCoinD.setChecked(MyApp.getInstance().getCashSetStructure().isCoinD5());
        binding.checkboxDevCoinC.setChecked(MyApp.getInstance().getCashSetStructure().isCoinC1());

        binding.cardDevBillF.setVisibility(MyApp.getInstance().getCashSetStructure().isBillF1000() ? View.VISIBLE : View.GONE);
        binding.cardDevBillE.setVisibility(MyApp.getInstance().getCashSetStructure().isBillE500() ? View.VISIBLE : View.GONE);
        binding.cardDevBillD.setVisibility(MyApp.getInstance().getCashSetStructure().isBillD100() ? View.VISIBLE : View.GONE);
        binding.cardDevCoinF.setVisibility(MyApp.getInstance().getCashSetStructure().isCoinF50() ? View.VISIBLE : View.GONE);
        binding.cardDevCoinE.setVisibility(MyApp.getInstance().getCashSetStructure().isCoinE10() ? View.VISIBLE : View.GONE);
        binding.cardDevCoinD.setVisibility(MyApp.getInstance().getCashSetStructure().isCoinD5() ? View.VISIBLE : View.GONE);
        binding.cardDevCoinC.setVisibility(MyApp.getInstance().getCashSetStructure().isCoinC1() ? View.VISIBLE : View.GONE);

        boolean isPickupEnabled = MyApp.getInstance().getDevSet().isPickupModule();
        binding.checkboxPickupModule.setChecked(isPickupEnabled);
        
        if (isPickupEnabled) {
            binding.textViewPickupStatusHint.setText("啟用中");
            binding.textViewPickupStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.success));
            binding.chipGroupPickup.setVisibility(View.VISIBLE);
        } else {
            binding.textViewPickupStatusHint.setText("功能未啟用");
            binding.textViewPickupStatusHint.setTextColor(androidx.core.content.ContextCompat.getColor(getCtx(), com.unibuy.smartdevice.R.color.warning));
            binding.chipGroupPickup.setVisibility(View.GONE);
        }

        binding.checkboxPickupCode.setChecked(MyApp.getInstance().getDevSet().isPickupCode());
        binding.checkboxPassCode.setChecked(MyApp.getInstance().getDevSet().isPassCode());

        binding.cardDevPickupCode.setVisibility(isPickupEnabled && MyApp.getInstance().getDevSet().isPickupCode() ? View.VISIBLE : View.GONE);
        binding.cardDevPassCode.setVisibility(isPickupEnabled && MyApp.getInstance().getDevSet().isPassCode() ? View.VISIBLE : View.GONE);

        binding.checkboxWelcomeGift.setChecked(MyApp.getInstance().getDevSet().isWelcomeGift());
        binding.checkboxMemberSystem.setChecked(MyApp.getInstance().getDevSet().isMemberSystem());
        binding.checkboxAmbientTemp.setChecked(MyApp.getInstance().getDevSet().isAmbientTemp());

        binding.cardDevWelcomeGift.setVisibility(MyApp.getInstance().getDevSet().isWelcomeGift() ? View.VISIBLE : View.GONE);
        binding.cardDevMemberSystem.setVisibility(MyApp.getInstance().getDevSet().isMemberSystem() ? View.VISIBLE : View.GONE);
        binding.cardDevAmbientTemp.setVisibility(MyApp.getInstance().getDevSet().isAmbientTemp() ? View.VISIBLE : View.GONE);

        setupSpringSlotRow(binding.rowSpringSlot110, binding.textSpringSlot110, MyApp.getInstance().getHardwareSetStructure().isSpringSlot1_10());
        setupSpringSlotRow(binding.rowSpringSlot1120, binding.textSpringSlot1120, MyApp.getInstance().getHardwareSetStructure().isSpringSlot11_20());
        setupSpringSlotRow(binding.rowSpringSlot2130, binding.textSpringSlot2130, MyApp.getInstance().getHardwareSetStructure().isSpringSlot21_30());
        setupSpringSlotRow(binding.rowSpringSlot3140, binding.textSpringSlot3140, MyApp.getInstance().getHardwareSetStructure().isSpringSlot31_40());
        setupSpringSlotRow(binding.rowSpringSlot4150, binding.textSpringSlot4150, MyApp.getInstance().getHardwareSetStructure().isSpringSlot41_50());
        setupSpringSlotRow(binding.rowSpringSlot5160, binding.textSpringSlot5160, MyApp.getInstance().getHardwareSetStructure().isSpringSlot51_60());
    }

    private void setupSpringSlotRow(TableRow row, TextView textMode, boolean isChecked) {
        textMode.setTag(isChecked);
        textMode.setText(isChecked ? "彈簧模式" : "履帶模式");
    }

    /** 依登入身分決定可否編輯：系統方僅可編輯硬體貨道並顯示儲存鈕；其餘全唯讀。 */
    private void applyRolePermission() {
        binding.buttonSave.setVisibility(View.GONE);
        refreshChildStates();
    }

    /**
     * 統一刷新所有 CheckBox 的 enabled 狀態。機台不可編輯系統設定：
     *  - 所有系統設定項（購物車/發票/各支付方式/刷卡機/掃碼/現金總開關與面額/取貨模組/
     *    來店禮/會員/環溫）→ 一律唯讀，真相在雲端後台，即使系統方也不可改。
     *  - 唯一例外：硬體貨道（彈簧/履帶）→ 僅系統方可改並寫回雲端，因只有現場技師最清楚
     *    各貨道的實際機械型式。
     */
    private void refreshChildStates() {
        // 系統設定項：恆唯讀（與身分、主開關都無關）
        setEnabled(false,
                binding.checkboxShoppingCar, binding.checkboxInvoice,
                binding.checkboxDevScanPay, binding.checkboxDevEsunPay, binding.checkboxDevTapPay,
                binding.checkboxDevLinePay,
                binding.checkboxDevTapPay30, binding.checkboxDevTapPay31, binding.checkboxDevTapPay32,
                binding.checkboxDevTapPay33, binding.checkboxDevTapPay34,
                binding.checkboxDevCash,
                binding.checkboxDevBillF, binding.checkboxDevBillE, binding.checkboxDevBillD,
                binding.checkboxDevCoinF, binding.checkboxDevCoinE, binding.checkboxDevCoinD,
                binding.checkboxDevCoinC,
                binding.checkboxPickupModule, binding.checkboxPickupCode, binding.checkboxPassCode,
                binding.checkboxWelcomeGift, binding.checkboxMemberSystem, binding.checkboxAmbientTemp);

        // 硬體貨道已改為全唯讀
    }

    private void setEnabled(boolean enabled, View... views) {
        for (View v : views) {
            v.setEnabled(enabled);
        }
    }

    /** 系統方按下儲存：先回寫雲端，成功後才更新本地並關閉。 */
    private void onSaveClicked() {
        if (!isSystem) return;
        binding.buttonSave.setEnabled(false);
        try {
            JSONObject settings = buildBackendSettings();
            new StarCloudAPI(getHandlerMain(), getHandlerMain()).uploadSystemSettings(settings,
                    new StarCloudAPI.SettingsUploadCallback() {
                        @Override
                        public void onSuccess() {
                            commitToLocal();
                            android.widget.Toast.makeText(getCtx(), "設定已儲存並回寫雲端", android.widget.Toast.LENGTH_SHORT).show();
                            finish();
                        }

                        @Override
                        public void onFailure(String message) {
                            binding.buttonSave.setEnabled(true);
                            android.widget.Toast.makeText(getCtx(), "儲存失敗：" + message, android.widget.Toast.LENGTH_LONG).show();
                        }
                    });
        } catch (JSONException e) {
            binding.buttonSave.setEnabled(true);
            android.widget.Toast.makeText(getCtx(), "設定組裝失敗：" + e.getMessage(), android.widget.Toast.LENGTH_LONG).show();
        }
    }

    /** 將目前 CheckBox 狀態寫回記憶體並持久化（本地）。 */
    private void commitToLocal() {
        MyApp.getInstance().getDevSet().setShoppingCar(binding.checkboxShoppingCar.isChecked());
        MyApp.getInstance().getDevSet().setInvoice(binding.checkboxInvoice.isChecked());
        MyApp.getInstance().getDevSet().setDevScanPay(binding.checkboxDevScanPay.isChecked());
        MyApp.getInstance().getDevSet().setDevEsunPay(binding.checkboxDevEsunPay.isChecked());
        MyApp.getInstance().getDevSet().setDevTapPay(binding.checkboxDevTapPay.isChecked());
        MyApp.getInstance().getDevSet().setTapPay30(binding.checkboxDevTapPay30.isChecked());
        MyApp.getInstance().getDevSet().setTapPay31(binding.checkboxDevTapPay31.isChecked());
        MyApp.getInstance().getDevSet().setTapPay32(binding.checkboxDevTapPay32.isChecked());
        MyApp.getInstance().getDevSet().setTapPay33(binding.checkboxDevTapPay33.isChecked());
        MyApp.getInstance().getDevSet().setTapPay34(binding.checkboxDevTapPay34.isChecked());
        MyApp.getInstance().getDevSet().setDevLinePay(binding.checkboxDevLinePay.isChecked());
        MyApp.getInstance().getDevSet().setDevCash(binding.checkboxDevCash.isChecked());

        MyApp.getInstance().getCashSetStructure().setBillF1000(binding.checkboxDevBillF.isChecked());
        MyApp.getInstance().getCashSetStructure().setBillE500(binding.checkboxDevBillE.isChecked());
        MyApp.getInstance().getCashSetStructure().setBillD100(binding.checkboxDevBillD.isChecked());
        MyApp.getInstance().getCashSetStructure().setCoinF50(binding.checkboxDevCoinF.isChecked());
        MyApp.getInstance().getCashSetStructure().setCoinE10(binding.checkboxDevCoinE.isChecked());
        MyApp.getInstance().getCashSetStructure().setCoinD5(binding.checkboxDevCoinD.isChecked());
        MyApp.getInstance().getCashSetStructure().setCoinC1(binding.checkboxDevCoinC.isChecked());

        MyApp.getInstance().getDevSet().setPickupModule(binding.checkboxPickupModule.isChecked());
        MyApp.getInstance().getDevSet().setPickupCode(binding.checkboxPickupCode.isChecked());
        MyApp.getInstance().getDevSet().setPassCode(binding.checkboxPassCode.isChecked());
        MyApp.getInstance().getDevSet().setWelcomeGift(binding.checkboxWelcomeGift.isChecked());
        MyApp.getInstance().getDevSet().setMemberSystem(binding.checkboxMemberSystem.isChecked());
        MyApp.getInstance().getDevSet().setAmbientTemp(binding.checkboxAmbientTemp.isChecked());

        MyApp.getInstance().getHardwareSetStructure().setSpringSlot1_10((Boolean) binding.textSpringSlot110.getTag());
        MyApp.getInstance().getHardwareSetStructure().setSpringSlot11_20((Boolean) binding.textSpringSlot1120.getTag());
        MyApp.getInstance().getHardwareSetStructure().setSpringSlot21_30((Boolean) binding.textSpringSlot2130.getTag());
        MyApp.getInstance().getHardwareSetStructure().setSpringSlot31_40((Boolean) binding.textSpringSlot3140.getTag());
        MyApp.getInstance().getHardwareSetStructure().setSpringSlot41_50((Boolean) binding.textSpringSlot4150.getTag());
        MyApp.getInstance().getHardwareSetStructure().setSpringSlot51_60((Boolean) binding.textSpringSlot5160.getTag());

        MyApp.saveSystemSet(getCtx());
    }

    /**
     * 組出回寫雲端用的 settings JSON。機台僅可編輯硬體貨道，故只送這六個 is_spring_slot_*
     * 欄位；B016 後端以 array_key_exists 逐欄位守門，未送的欄位保持原值，避免用本地舊值
     * 覆寫雲端後台可能已更新的其他設定。
     */
    private JSONObject buildBackendSettings() throws JSONException {
        JSONObject s = new JSONObject();
        s.put("is_spring_slot_1_10", (Boolean) binding.textSpringSlot110.getTag());
        s.put("is_spring_slot_11_20", (Boolean) binding.textSpringSlot1120.getTag());
        s.put("is_spring_slot_21_30", (Boolean) binding.textSpringSlot2130.getTag());
        s.put("is_spring_slot_31_40", (Boolean) binding.textSpringSlot3140.getTag());
        s.put("is_spring_slot_41_50", (Boolean) binding.textSpringSlot4150.getTag());
        s.put("is_spring_slot_51_60", (Boolean) binding.textSpringSlot5160.getTag());
        return s;
    }
}
