package com.unibuy.smartdevice.tools;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * 現金收銀機（MDB232 轉換盒）傳輸層工廠。
 *
 * <p>目標機台的收銀轉換盒(MDB232)可透過三種接法連線，由使用者在「系統設定 → 現金機設定」頁選擇；
 * 三者皆為串口，統一由 {@link SerialCashAcceptorHandler}(Modbus) 處理，只差 /dev 路徑：</p>
 * <ul>
 *     <li>{@link ConnType#USB}：USB 轉 RS-232 轉接器 = /dev/ttyUSB0（讀取快又乾淨→即時，推薦；非 Android UsbManager 機制）</li>
 *     <li>{@link ConnType#COM_PORT_3}：原生串口 Com Port 3 = /dev/ttyS3（緩衝延遲大，硬幣判斷會慢/漏）</li>
 *     <li>{@link ConnType#TTYS9}：原生串口 = /dev/ttyS9</li>
 * </ul>
 *
 * <p>選擇後持久化於 SharedPreferences；{@link #create(Context, MdbEventListener)} 依設定回傳對應
 * 傳輸實體。所有消費端（CashPayDialogGeneral / CashPayoutManager / CashMachineSettings）一律
 * 透過本工廠取得 {@link ICashAcceptorHandler}，確保三處使用同一連線設定。</p>
 */
public final class CashAcceptorFactory {

    private static final String PREFS_NAME = "cash_connection_prefs";
    private static final String KEY_CONN_TYPE = "conn_type";

    /** USB 轉 RS-232 轉接器的串口節點（USB 選項用；讀取快又乾淨→硬幣即時偵測，推薦）。 */
    public static final String PATH_USB = "/dev/ttyUSB0";

    /** ttyS9 串口路徑。 */
    public static final String PATH_TTYS9 = "/dev/ttyS9";

    /**
     * Com Port 3 串口路徑 = /dev/ttyS3。
     * 某台 Android 9 IPC 有三個 com port，第三個 ttyS3 專接現金 MDB232 轉換盒。
     */
    public static final String PATH_COM_PORT_3 = "/dev/ttyS3";

    public enum ConnType {
        USB,
        COM_PORT_3,
        TTYS9
    }

    private CashAcceptorFactory() {
    }

    private static SharedPreferences prefs(Context context) {
        return context.getApplicationContext()
                .getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    }

    /** 讀取目前選擇的連線方式，預設 USB（維持既有行為）。 */
    public static ConnType getConnType(Context context) {
        String name = prefs(context).getString(KEY_CONN_TYPE, ConnType.USB.name());
        try {
            return ConnType.valueOf(name);
        } catch (IllegalArgumentException e) {
            return ConnType.USB;
        }
    }

    /** 儲存使用者在設定頁選擇的連線方式。 */
    public static void setConnType(Context context, ConnType type) {
        prefs(context).edit().putString(KEY_CONN_TYPE, type.name()).apply();
    }

    /**
     * 依目前設定建立對應的收銀傳輸實體。
     *
     * @param context  Context
     * @param listener 事件監聽器（可為 null）
     * @return USB 或串口（ttyS9 / Com Port 3）handler
     */
    public static ICashAcceptorHandler create(Context context, MdbEventListener listener) {
        switch (getConnType(context)) {
            case COM_PORT_3:
                return new SerialCashAcceptorHandler(context, listener, null, PATH_COM_PORT_3);
            case TTYS9:
                return new SerialCashAcceptorHandler(context, listener, null, PATH_TTYS9);
            case USB:
            default:
                // USB = USB 轉 RS-232 轉接器(/dev/ttyUSB0) 走串口，非 Android UsbManager。這是即時的推薦接法。
                return new SerialCashAcceptorHandler(context, listener, null, PATH_USB);
        }
    }
}
