using System.Collections.Generic;
using UnityEngine;
using ArduinoBluetoothAPI;
using System;
using System.Text;
using UnityEngine.UI;
using DG.Tweening;

namespace InfraredManager
{
    public class ConnetDevicesSingle : MonoBehaviour
    {

        #region 连接弓箭蓝牙部分
        private BluetoothHelper bluetoothHelperBow;
        public BluetoothHelper mBluetoothHelperBow
        {
            get
            {
                return bluetoothHelperBow;
            }
        }
        private BluetoothHelperCharacteristic characteristicWriteBow;
        private BluetoothHelperService bluetoothServiceBow;
        private string bowTargetDeviceName = "Bbow_20210501";
        private string bowDeviceName = "";
        string bowDeviceService = "0000fff0";
        string bowDeviceCharacteristicWrite = "0000fff2";
        string bowDeviceCharacteristicNotify = "0000fff1";
        private bool isBowScanning;
        public bool mIsBowScanning
        {
            get
            {
                return isBowScanning;
            }
        }
        private bool isBowConnecting;
        public bool mIsBowConnecting
        {
            get
            {
                return isBowConnecting;
            }
        }
        private string data;
        #endregion

        private LinkedList<BluetoothDevice> devices;

        #region log输出
        public Action<string> OnLogAction;
        void logOutBow(string text)
        {
            Debug.Log("logOutBow:" + text);
            OnLogAction?.Invoke(text);
        }
        #endregion

        public static ConnetDevicesSingle ins;

        //默认关闭准心
        public bool bCrosshair = false;

        #region 红外Demo相关监听操作
        public Action<Vector3> posAction;
        public Action<int> infraredShootAction;
        public Action<bool> crosshairAction;
        #endregion

        void Awake()
        {
            //初始化
            ins = this;
            Debug.Log("ConnetDevicesSingle！");
            InitAutoDormancy();

            OnUpdateState();

        }
        //获取一次初始值
        public void OnInitConfig()
        {

        }
        public void OnUpdateState()
        {

        }

        public void ButtonShoot()
        {



            posAction?.Invoke(new Vector3(1 * Screen.width, 1 * Screen.height, 0));
            //调用游戏中的射箭接口
            if (ArmBow.ins)
            {
                ArmBow.ins.ADS_fire(true);
            }
            else
            {
                OnGameShoot?.Invoke(10);
            }
        }

        public void onShowCrosshair()
        {
            //显示游戏光标
            PlayerPrefs.SetInt("CrossHairImageActive", 1);
            bCrosshair = true;
            crosshairAction?.Invoke(true);

        }
        public void onHideCrosshair()
        {
            //隐藏游戏光标
            PlayerPrefs.SetInt("CrossHairImageActive", 0);
            bCrosshair = false;
            crosshairAction?.Invoke(false);


        }
        // Start is called before the first frame update
        void Start()
        {
            logOutBow("初始化BluetoothHelperAndroid");

            if (BluetoothHelperAndroid.IsBluetoothEnabled() == false)
            {
                Debug.Log("蓝牙未打开！");
                logOutBow("蓝牙未打开!");
                return;
            }

            data = "";
            try
            {


                BluetoothHelper.BLE = true;

                bluetoothHelperBow = BluetoothHelper.GetInstance();
                bluetoothHelperBow.OnConnected += OnConnected;
                bluetoothHelperBow.OnConnectionFailed += OnConnectionFailed;
                bluetoothHelperBow.OnScanEnded += OnScanEnded2;
                bluetoothHelperBow.OnCharacteristicChanged += (helper, value, characteristic) =>
                {
                    // Debug.Log(characteristic.getName());
                    // Debug.Log(System.Text.Encoding.ASCII.GetString(value));
                    byte[] bytes = value;
                    // Debug.Log("瞄准模块数据长度" + bytes.Length);
                    if (bytes.Length != 27 && bytes.Length != 39)
                    {
                        if (bytes[0] == 0x5b)
                        {
                            //红外射击检测
                            ShootByInfrared(bytes);
                        }
                    }
                };

            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }



        }

        //Bow扫描结束
        void OnScanEnded2(BluetoothHelper helper, LinkedList<BluetoothDevice> nearbyDevices)
        {
            Debug.Log("2 ended " + nearbyDevices.Count);
            logOutBow("2 ended " + nearbyDevices.Count);
            if (nearbyDevices.Count == 0)
            {
                isBowScanning = helper.ScanNearbyDevices();
                return;
            }
            isBowScanning = false;
            foreach (BluetoothDevice device in nearbyDevices)
            {
                Debug.Log(device.DeviceName);
                if (device.DeviceName == bowTargetDeviceName)
                {
                    logOutBow("匹配设备 " + device.DeviceName);
                    bowDeviceName = bowTargetDeviceName;
                    helper.setDeviceName(bowDeviceName);
                    helper.Connect();
                    isBowConnecting = true;
                }
            }
        }

        void OnConnected(BluetoothHelper helper)
        {
            if (helper.getId() == bluetoothHelperBow.getId())
            {
                Debug.Log("2 连接成功:" + helper.getDeviceName());
                logOutBow("弓箭 连接成功:" + helper.getDeviceName());
                isBowConnecting = false;
                foreach (BluetoothHelperService service in helper.getGattServices())
                {
                    if (service.getName().ToLower().StartsWith(bowDeviceService))
                    {
                        bluetoothServiceBow = service;
                        foreach (BluetoothHelperCharacteristic characteristic in service.getCharacteristics())
                        {
                            if (characteristic.getName().ToLower().StartsWith(bowDeviceCharacteristicWrite))
                            {
                                characteristicWriteBow = characteristic;
                            }
                            else if (characteristic.getName().ToLower().StartsWith(bowDeviceCharacteristicNotify))
                            {
                                BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristic.getName());
                                ch.setService(bluetoothServiceBow.getName());
                                bluetoothHelperBow.Subscribe(ch);
                            }
                        }
                    }
                }

                CallDelay(2, () =>
                {
                    //if (status != BluetoothStatusEnum.ConnectSuccess) return;
                    InitWhenConenct();

                });
            }

        }

        void OnConnectionFailed(BluetoothHelper helper)
        {

            Debug.Log("Connection lost");
            if (helper.getId() == bluetoothHelperBow.getId())
            {
                isBowConnecting = false;
                logOutBow("弓箭断开连接");
            }
        }


        //Connect bow ble
        public void OnBowScanNearbyDevices()
        {
            if (bluetoothHelperBow == null)
                return;
            if (!bluetoothHelperBow.isConnected() && !isBowScanning && !isBowConnecting)
            {
                //未连接，未扫描，不是连接中
                if (BluetoothHelperAndroid.IsBluetoothEnabled() == false)
                {
                    Debug.Log("exception1");
                    logOutBow("蓝牙未打开");
                    return;
                }

                if (BluetoothHelperAndroid.RequestBluetoothPermissions(() =>
                {
                    //开始扫描。调用最后一个bluetoothHelperBow扫描即可
                    isBowScanning = bluetoothHelperBow.ScanNearbyDevices();
                    logOutBow("开始扫描连接！");
                }, (permission) =>
                {
                    if (permission.Contains("LOCATION"))
                    {
                        Debug.LogError("Exception：LOCATION");
                        logOutBow("Exception：LOCATION");
                    }
                    else if (permission.Contains("BLUETOOTH"))
                    {
                        Debug.LogError("Exception： BLUETOOTH");
                        logOutBow("Exception：BLUETOOTH");
                    }
                })) return;
                isBowScanning = bluetoothHelperBow.ScanNearbyDevices();
                logOutBow("开始扫描连接！");
            }
            else if (!bluetoothHelperBow.isConnected() && isBowScanning)
            {
                //扫描中
                logOutBow("扫描中...");
            }
            else if (bluetoothHelperBow.isConnected())
            {
                logOutBow("断开Bow连接");
                //已连接，断开连接
                bluetoothHelperBow.Disconnect();
            }
        }


        void OnDestroy()
        {

            if (bluetoothHelperBow != null)
            {
                bluetoothHelperBow.Disconnect();
                OnDisconnect();
            }

        }

        /// <summary>
        /// 字节数组转16进制字符串：空格分隔
        /// </summary>
        /// <param name="byteDatas"></param>
        /// <returns></returns>
        public string ToHexStrFromByte(byte[] byteDatas)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < byteDatas.Length; i++)
            {
                builder.Append(string.Format("{0:X2} ", byteDatas[i]));
            }
            return builder.ToString().Trim();
        }
        /// <summary>
        /// 字符串转16进制
        /// </summary>
        /// <param name="input">要转格式的字符串</param>

        public byte[] Convert16(string strText)
        {
            strText = strText.Replace(" ", "");
            strText = strText.Replace(" ", "");
            Debug.Log(strText);
            byte[] bText = new byte[strText.Length / 2];
            for (int i = 0; i < strText.Length / 2; i++)
            {
                bText[i] = Convert.ToByte(Convert.ToInt32(strText.Substring(i * 2, 2), 16));
            }
            return bText;
        }




        string getBytesToIndex(byte[] bytes, int index)
        {
            StringBuilder builderCrosshair = new StringBuilder();
            builderCrosshair.Append(string.Format("{0:X2}", bytes[index]));
            return builderCrosshair.ToString().Trim();
        }
        float onVectorValue(byte[] bytes, int startIndex)
        {
            //整数部分
            string intPartHex = string.Format("{0:X2}", bytes[startIndex]).ToString().Trim(); ;
            int intPartNumber = Convert.ToInt32(intPartHex, 16);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 2; i++)
            {
                builder.Append(string.Format("{0:X2}", bytes[i + startIndex + 1]));
            }
            string dataHex = builder.ToString().Trim();
            int decimalPartNumber = Convert.ToInt32(dataHex, 16);
            return intPartNumber + (float)decimalPartNumber / 32768;
        }


        void CallDelay(float delayTime, TweenCallback callback)
        {
            Sequence sequence = DOTween.Sequence();
            sequence.PrependInterval(delayTime).AppendCallback(callback);
            sequence.SetUpdate(true);
        }

        #region 自动进入/退出休眠状态, 这里做程指令发送队列，为了控制连续发送指令的间隔，避免硬件收不到或处理不过来
        class CmdToSend
        {
            public string[] cmds;
            public Action onComplete;
            public Func<bool> canDo;
            public CmdToSend(string[] cmds, Action onComplete, Func<bool> canDo)
            {
                this.cmds = cmds;
                this.onComplete = onComplete;
                this.canDo = canDo;
            }
        }
        Queue<CmdToSend> cmdWaitingList = new Queue<CmdToSend>();
        bool isSendCmdLocked = false;
        bool canAutoDormancy = false;
        bool isStartUp = false;
        JCUnityLib.CountLock needModularAwake = new JCUnityLib.CountLock();

        void InitAutoDormancy()
        {
            //暂时关闭自动休眠，默认是需要模块保持激活
            needModularAwake.Lock();
        }
        void InitWhenConenct()
        {
            canAutoDormancy = true;
            List<string> cmds = new List<string>();
            cmds.Add("M"); //获取Mac地址
            cmds.Add("b"); //确保开启stm32
            cmds.Add("b"); //获取初始电量
            cmds.Add("1"); //开启发送逻辑
            Action onComplete = null;
            if (needModularAwake.IsLocked())
            {
                cmds.Add("w"); //红外灯开启
                //cmds.Add("3"); //九轴开启
                onComplete = () =>
                {
                    isStartUp = true;
                };
            }
            else
            {
                cmds.Add("s"); //红外灯关闭
                cmds.Add("S"); //Stm32关闭
                //cmds.Add("4"); //九轴关闭
                onComplete = () =>
                {
                    isStartUp = false;
                };
            }
            SendCDM(null, onComplete, cmds.ToArray());
        }
        void DestroyWhenDisconenct()
        {
            canAutoDormancy = false;
            sendCMD_CheckAndDoStop(null);

        }
        //启动
        void StartUp()
        {
            SendCDM(() =>
            {
                return !isStartUp;
            }, () =>
            {
                isStartUp = true;
            }, "b", "w", "3");
        }
        void SendCDM(Func<bool> canDo, Action onComplete, params string[] cmds)
        {
            CmdToSend cmdToSend = new CmdToSend(cmds, onComplete, canDo);
            if (isSendCmdLocked)
            {
                cmdWaitingList.Enqueue(cmdToSend);
                return;
            }
            sendCMD_NotCheck(cmdToSend);
        }
        void sendCMD_NotCheck(CmdToSend cmdToSend)
        {
            if (cmdToSend.canDo != null && !cmdToSend.canDo.Invoke())
            {
                sendCMD_CheckNext();
                return;
            }
            isSendCmdLocked = true;
            Sequence sequence = DOTween.Sequence();
            sequence.PrependInterval(0.3f);
            foreach (var cmd in cmdToSend.cmds)
            {
                sequence.AppendCallback(() =>
                {
                    bool stopped = sendCMD_CheckAndDoStop(sequence);
                    if (!stopped) onWriteDataToBow(cmd);
                });
                sequence.AppendInterval(0.5f);
            }
            sequence.AppendCallback(() =>
            {
                bool stopped = sendCMD_CheckAndDoStop(sequence);
                if (!stopped)
                {
                    isSendCmdLocked = false;
                    cmdToSend.onComplete?.Invoke();
                    sendCMD_CheckNext();
                }
            });
            sequence.SetUpdate(true);
        }
        void sendCMD_CheckNext()
        {
            if (cmdWaitingList.Count <= 0) return;
            CmdToSend cmdToSend = cmdWaitingList.Dequeue();
            sendCMD_NotCheck(cmdToSend);
        }
        bool sendCMD_CheckAndDoStop(Sequence sequence)
        {
            if (canAutoDormancy) return false;
            isStartUp = false;
            isSendCmdLocked = false;
            cmdWaitingList.Clear();
            if (sequence != null) sequence.Kill();
            return true;
        }
        #endregion
        #region 弓箭部分代码操作
        public Action<float> OnGameShoot;
        [NonSerialized] public byte byteTime1;
        [NonSerialized] public byte byteTime2;
        /**通过红外线数据进行射击 */
        public void ShootByInfrared(byte[] bytes)
        {
            byteTime1 = bytes[2];
            byteTime1 = bytes[3];
            int id = bytes[1]; //序号
            float time1 = bytes[2] * 0.1f; //时区1耗时
            float time2 = bytes[3] * 0.1f; //时区2耗时
            float totalTime = time1 + time2;

            //校验和
            int sumCheck = bytes[0] + bytes[1] + bytes[2] + bytes[3];
            sumCheck &= 0xff;
            //校验和比较结果
            bool sumCheckRes = sumCheck == bytes[4];
            //弓轨速度
            float speed = 0.05f / (totalTime / 1000f);
            //通过动能定理求箭的速度（实体箭质量*实体箭速度^2=游戏中箭的质量*游戏中箭的速度^2）
            float shootSpeed = Mathf.Sqrt(speed * speed * CommonConfig.arrowWeight / UserSettings.ins.actualArrowWeight);
            //打印
            string logTxt = $"序号{id}，时区1：{time1}毫秒，时区2：{time2}毫秒，校验：{sumCheckRes}，弓轨速度：{speed}m/s，箭的速度：{shootSpeed}m/s";
            logOutBow(logTxt);
            // if (DebugForDevice.ins) DebugForDevice.ins.LogInfrared(logTxt);
            //收到射箭数据，就回复硬件，否则n毫秒后硬件会认为丢包进行重传
            try
            {
                if (sumCheckRes) ReplyInfraredShoot(); //如果数据正确，则回复硬件
            }
            catch (Exception) { }

            //打开准心的时候，直接调用射击接口
            if (ArmBow.ins)
            {
                ArmBow.ins.ADS_fire(true);
            }
            else if (DuckHunter.SmartBowController.Instance)
            {
                DuckHunter.SmartBowController.Instance.OnShooting(shootSpeed);
            }
            //else
            //{
            //    OnGameShoot?.Invoke(shootSpeed);
            //}



        }
        //断开弓箭连接
        void OnDisconnect()
        {
            DestroyWhenDisconenct();
        }
        public void RequestBattery()
        {
            if (!isStartUp) return;
            if (isSendCmdLocked) return;
            onWriteDataToBow("b");
        }
        //回复弓箭红外
        public void ReplyInfraredShoot()
        {
            if (isSendCmdLocked) return;
            onWriteDataToBow("I");
        }
        public void onWriteDataToBow(string data)
        {
            BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristicWriteBow.getName());
            ch.setService(bluetoothServiceBow.getName());
            bluetoothHelperBow.WriteCharacteristic(ch, data);
        }
        #endregion
    }
}