using Microsoft.ReactNative.Managed;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using WinRT.BxlComponent.Plugin.BxlMpXamarinSDK.Abstractions;

namespace WinRT.BxlComponent.UwpWrapper
{
    [ReactModule]
    public sealed class MPosControllerConfigProxy
    {
        private Plugin.BxlMpXamarinSDK.MposConfigurationImplementation _configDev;
        private static int _uniqueDeviceId = 1024;
        public event EventHandler<string> statusUpdateEvent;
        public event EventHandler<string> dataEvent;
        public MPosControllerConfigProxy()
        {
            _configDev = new Plugin.BxlMpXamarinSDK.MposConfigurationImplementation((int)MPosDeviceType.MPOS_DEVICE_CONFIG, _uniqueDeviceId++);
        }
        [ReactMethod("selectInterface")]
        public void selectInterface(string[] array, IReactPromise<int> promise)
        {
            promise.Resolve(_configDev.selectInterface(
                Convert.ToInt32(array[0]),
                array[1])
                );
            return;
        }
        [ReactMethod("selectCommandMode")]
        public void selectCommandMode(int commandMode, IReactPromise<int> promise)
        {
            promise.Resolve(_configDev.selectCommandMode(commandMode));
            return;
        }
        [ReactMethod("openService")]
        public async void openService(uint[] array, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.openService(
                array[0],
                array[1]
                ));
            return;
        }
        [ReactMethod("closeService")]
        public async void closeService(uint closeTimeout/*second*/, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.closeService(closeTimeout));
            return;
        }
        [ReactMethod("isOpen")]
        public void isOpen(IReactPromise<int> promise)
        {
            promise.Resolve(Convert.ToInt32(_configDev.isOpen()));
            return;
        }
        [ReactMethod("getDeviceId")]
        public void getDeviceId(IReactPromise<int> promise)
        {
            //promise.Resolve(Convert.ToInt32(_configDev.getDeviceId()));
            promise.Resolve(Convert.ToInt32(_configDev.DeviceID));
            return;
        }
        [ReactMethod("directIO")]
        public async void directIO([ReadOnlyArray()] byte[] data, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.directIO(data));
            return;
        }
        [ReactMethod("setTransaction")]
        public async void setTransaction(int transactionMode, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.setTransaction(transactionMode));
            return;
        }

        // MAUI SDK
        [ReactMethod("searchDevices")]
        public async void searchDevices(IReactPromise<IList<int>> promise)
        {
            promise.Resolve(await _configDev.searchDevices());
            return;
        }

        // RN SDK - OpenService에서 막히니 여기까지 오지도 못함
        //[ReactMethod("searchDevices")]
        //public IAsyncOperation<IList<int>> searchDevices()
        //{
        //    return Task.Run<IList<int>>(async () =>
        //    {
        //        IList<int> devList = null;
        //        await _configDev.searchDevices((list) =>
        //        {
        //            devList = list;
        //        });
        //        return devList;
        //    }).AsAsyncOperation();
        //}

        [ReactMethod("getBgateSerialNumber")]
        public async void getBgateSerialNumber(IReactPromise<string> promise)
        {
            promise.Resolve(await _configDev.getBgateSerialNumber());
            return;
        }
               
        // RN SDK
        //[ReactMethod("getSerialConfig")]
        //public async void getSerialConfig(int targetDeviceID, IReactPromise<IList<int>> promise)
        //{
        //    promise.Resolve(await _configDev.getSerialConfig(targetDeviceID));
        //    return;
        //}
        
        [ReactMethod("getSerialConfig")]
        //[ReactMethod("getSerialConfiguration")]
        public async void getSerialConfiguration(int targetDeviceID, IReactPromise<IList<int>> promise)
        {
            promise.Resolve(await _configDev.getSerialConfiguration(targetDeviceID));
            return;
        }

        // RN SDK
        //[ReactMethod("setSerialConfig")]
        //public async void setSerialConfig(int[] array, IReactPromise<int> promise) //int devID, int baudRate, int dataBit, int stopBit, int parityBit
        //{
        //    promise.Resolve(await _configDev.setSerialConfig(
        //        array[0],
        //        array[1],
        //        array[2],
        //        array[3],
        //        array[4]
        //        ));
        //    return;
        //}

        [ReactMethod("setSerialConfig")]
        //[ReactMethod("setSerialConfiguration")]
        public async void setSerialConfiguration(int[] array, IReactPromise<int> promise) //int devID, int baudRate, int dataBit, int stopBit, int parityBit, int flowControl
        {
            promise.Resolve(await _configDev.setSerialConfiguration(
                array[0],
                array[1],
                array[2],
                array[3],
                array[4],
                array[5]
                ));
            return;
        }
        [ReactMethod("getUSBDevice")]
        public async void getUSBDevice(int targetDeviceID, IReactPromise<string> promise)
        {
            promise.Resolve(await _configDev.getUSBDevice(targetDeviceID));
            return;
        }
        [ReactMethod("getCustomDevices")]
        public async void getCustomDevices(int DeviceType, IReactPromise<string> promise)
        {
            promise.Resolve(await _configDev.getCustomDevices(DeviceType));
            return;
        }
        [ReactMethod("addCustomDevice")]
        public async void addCustomDevice(int DeviceType, string vid, string pid, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.addCustomDevice(DeviceType, vid, pid));
            return;
        }
        [ReactMethod("deleteCustomDevice")]
        public async void deleteCustomDevice(int DeviceType, string vid, string pid, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.deleteCustomDevice(DeviceType, vid, pid));
            return;
        }
        [ReactMethod("reInitCustomDeviceType")]
        public async void reInitCustomDeviceType(int DeviceType, IReactPromise<int> promise)
        {
            promise.Resolve(await _configDev.reInitCustomDeviceType(DeviceType));
            return;
        }
    }
}