package acquire.sdk.device;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;

import com.morefun.yapi.ServiceResult;
import com.morefun.yapi.device.reader.icc.IccCardReader;
import com.morefun.yapi.device.reader.icc.IccReaderSlot;
import com.morefun.yapi.device.reader.mag.MagCardReader;
import com.morefun.yapi.engine.DeviceInfoConstrants;
import com.newland.nsdk.core.api.common.ModuleType;
import com.newland.nsdk.core.api.common.exception.NSDKException;
import com.newland.nsdk.core.api.internal.devicemanager.DeviceManager;
import com.newland.nsdk.core.internal.NSDKModuleManagerImpl;

import java.util.Date;

import acquire.base.utils.LoggerUtils;
import acquire.sdk.DeviceHelper;
import acquire.sdk.device.constant.Model;

/**
 * Device information
 *
 * @author Janson
 * @date 2018/3/1
 */
public class BDevice {

    /**
     * set POS system time
     * <p><hr><b>e.g.</b></p>
     * <pre>
     *        Calendar calendar = Calendar.getInstance();
     *        //change time:
     *        //calendar.set(xxx);
     *        Date date = calendar.getTime();
     *        BDevice.setSystemTime(data);
     * </pre>
     *
     * @param date date instant.
     */
    public static void setSystemTime(Date date) {
        try {
            DeviceManager deviceManager = (DeviceManager) NSDKModuleManagerImpl.getInstance().getModule(ModuleType.DEVICE_MANAGER);
            deviceManager.setPOSDate(date);
        } catch (NSDKException e) {
            e.printStackTrace();
        }
    }

    /**
     * Return true if this device has security module.
     **/
    public static boolean isExistSecurityModule() {
        DeviceManager deviceManager = (DeviceManager) NSDKModuleManagerImpl.getInstance().getModule(ModuleType.DEVICE_MANAGER);
        return deviceManager.isExistSecurityModule();
    }

    /**
     * Get sdk version
     *
     * @return sdk version
     **/
    public static String getSdkVersion() {
        DeviceManager deviceManager = (DeviceManager) NSDKModuleManagerImpl.getInstance().getModule(ModuleType.DEVICE_MANAGER);
        return deviceManager.getSDKVersion();
    }


    /**
     * Get the device information
     */
    private static Bundle getDeviceInfo() throws NSDKException, RemoteException {
        return  DeviceHelper.getDeviceService().getDevInfo();
    }

    /**
     * Get the sequence number
     *
     * @return device sequence number
     */
    public static String getSn() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                //return "98250623730002";
                return deviceInfo.getString(DeviceInfoConstrants.COMMOM_SN);
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * Get the manufacturer serial number
     *
     * @return manufacturer serial number .
     */
    public static String getCsn() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return deviceInfo.getString(DeviceInfoConstrants.COMMOM_SN);
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * Get the device model.
     *
     * @return The device model
     */
    public static String getDeviceModel() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return deviceInfo.getString(DeviceInfoConstrants.COMMOM_MODEL_EX);
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * device is CPOS (cash register)
     */
    public static boolean isCpos() {
        String model = getDeviceModel();
        if (model == null) {
            return false;
        } else {
            return model.contains("CPOS");
        }
    }


    /**
     * Get the firmware version number
     *
     * @return Firmware version
     */
    public static String getFirmwareVersion() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return deviceInfo.getString(DeviceInfoConstrants.COMMOM_OS_VER);
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * Return true if this device supports printing.
     */
    public static boolean supportPrint() {
        try {
            int ret = DeviceHelper.getPrinter().getStatus();
            Log.i("Printer", getResult(ret));
            return (ret == ServiceResult.Success);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private static String getResult(int code) {
        switch (code) {
            case ServiceResult.Success:
                return "Success";
            case ServiceResult.Printer_Print_Fail:
                return "Printer Fail";
            case ServiceResult.Printer_Busy:
                return "Busy";
            case ServiceResult.Printer_PaperLack:
                return "Paper Lack";
            default:
                return "Other Error";
        }
    }

    /**
     * Return true if this device supports inserting card.
     */
    public static boolean supportInsert() {
        try {
            final IccCardReader iccCardReader = DeviceHelper.getIccCardReader(IccReaderSlot.ICSlOT1);
            if (null != iccCardReader) {
                return true;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }



    /**
     * Return true if this device supports rfid card.
     */
    public static boolean supportRf() {
        try {
            final IccCardReader rfReader = DeviceHelper.getIccCardReader(IccReaderSlot.RFSlOT);
            if (null != rfReader) {
                return true;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }



    /**
     * Return true if this device supports mag card.
     */
    public static boolean supportMag() {
        try {
            final MagCardReader magCardReader = DeviceHelper.getMagCardReader();
            if (null != magCardReader) {
                return true;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * Return true if this device supports external scanner by USB.
     */
    public static boolean supportUsbHost() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return false; //deviceInfo.isSupportUSB()
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Return true if this device supports external PIN pad
     */
    public static boolean supportExternalPinPad() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return false; //deviceInfo.isSupportPinpadPort()
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Return true if this device supports RS232 serial port
     */
    public static boolean supportExternalRs232() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return false;//deviceInfo.isSupport232Port();
            }
        } catch (NSDKException| RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static int getLedConfig() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return -1; //deviceInfo.getLEDConfig();
            }
        } catch (NSDKException| RemoteException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static void initAuxLcd() {
        try {
            Bundle bundle = new Bundle();
            bundle.putBoolean(DeviceInfoConstrants.INIT_AUXLCD, true);
            DeviceHelper.getDeviceService().setProperties(bundle);
        } catch (RemoteException e) {
            LoggerUtils.e("Failed to init AUX LCD", e);
        }
    }

    public static void showAuxLcdLight() {
        try {
            Bundle bundle = new Bundle();
            bundle.putBoolean(DeviceInfoConstrants.LIGHT_AUXLCD, true);
            DeviceHelper.getDeviceService().setProperties(bundle);
        } catch (RemoteException e) {
            LoggerUtils.e("Failed to set AUX LCD light property", e);
        }
    }

    public static void showAuxLcd(Bitmap bitmap) {
        try {
            Bundle bundle = new Bundle();
            bundle.putBoolean(DeviceInfoConstrants.SHOW_AUXLCD, true);
            bundle.putParcelable(DeviceInfoConstrants.AUXLCD_BITMAP, bitmap);
            DeviceHelper.getDeviceService().setProperties(bundle);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    
    }

    public static void showAuxLcdFlush() {
        try {
            Bundle bundle = new Bundle();
            bundle.putBoolean(DeviceInfoConstrants.FLUSH_AUXLCD, true);
            DeviceHelper.getDeviceService().setProperties(bundle);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    
    }

    /**
     * Return true if this device supports hard scanner
     */
    public static boolean supportHardScanner() {
        try {
            Bundle deviceInfo = getDeviceInfo();
            if (null != deviceInfo) {
                return false;// deviceInfo.getScannerConfig().supportHardScanning();
            }
        } catch (NSDKException | RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Return true if this device has physical keyboard
     */
    public static boolean supportPhysicalKeyboard() {
        String model = getDeviceModel();
        return Model.P300.equals(model);
    }


}