using SC.InputSystem;
using SC.InputSystem.InputDeviceHandShank;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR;
using WCQ.CommonV1_20200325;

public class ControllerInputFromAction : MonoBehaviour
{
    public ControllerIndex index = ControllerIndex.Left;
    public List<InputActionReference> listinput;
    public List<InputActionReference> listtrack;

    public Transform Controller
    {
        get {
            return GetController(index)?.inputDeviceHandShankUI.transform;
        }
    }

    private void Start() {
        SC.InputSystem.InputSystem.ISInitializeCallBack += InputSystemVaildCallBack;
    }

    private void OnDestroy() {
        SC.InputSystem.InputSystem.ISInitializeCallBack -= InputSystemVaildCallBack;
    }

    private void Update()
    {
        //GetController(index)?.gameObject.SetActive(true);
        //if (index == ControllerIndex.Left)
        //    InputDataHandShank.HSData.HS0Connect = true;
        //else
        //    InputDataHandShank.HSData.HS1Connect = true;

        //if (GetController(index))
        //{

        //    GetController(index).inputDataHandShank.blueToothName = "K07";
        //    GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
        //    GetController(index).inputDataHandShank.isVaild = true;
        //}

        //Debug.Log("LateUpdate  " + GetController(index).inputDataHandShank.rotation);
    }

    void InputSystemVaildCallBack()
    {
        Invoke("DelayInvoke", 1);
    }

    void DelayInvoke() {
        Debug.Log("InputSystem Initialize ===" + index + " ");

        var HandedControllers = new List<UnityEngine.XR.InputDevice>();
        var desiredCharacteristics = (index == ControllerIndex.Left ? UnityEngine.XR.InputDeviceCharacteristics.Left : UnityEngine.XR.InputDeviceCharacteristics.Right) | UnityEngine.XR.InputDeviceCharacteristics.Controller;
        UnityEngine.XR.InputDevices.GetDevicesWithCharacteristics(desiredCharacteristics, HandedControllers);

        Debug.Log(HandedControllers.Count + "  ===========");

        foreach (var device in HandedControllers)
        {
            Debug.Log(string.Format("Device name '{0}' has characteristics '{1}'", device.name, device.characteristics.ToString()));
        }

        if (HandedControllers.Count == 1)
        {
            onDeviceConnected(HandedControllers[0]);
        }

        if (Application.platform != RuntimePlatform.Android)
        {
            onDeviceConnected(new UnityEngine.XR.InputDevice());
        }


        InputDevices.deviceConnected += onDeviceConnected;
        InputDevices.deviceDisconnected += onDeviceDisConnected;

    }
    private void onDeviceDisConnected(UnityEngine.XR.InputDevice obj) {
        if (Application.platform == RuntimePlatform.Android)
        {
            if (obj.characteristics.ToString().Contains(InputDeviceCharacteristics.Left.ToString()))
            {
                Debug.Log("Left onDeviceDisConnected===>" + index);
                InputDataHandShank.HSData.HS0Connect = false;
                GetController(ControllerIndex.Left)?.gameObject.SetActive(false);

                GetController(index).inputDataHandShank.blueToothName = "K07";
                GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
                GetController(index).inputDataHandShank.isVaild = false;

                GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack -= updateRotationCallBack;
            }

            if (obj.characteristics.ToString().Contains(InputDeviceCharacteristics.Right.ToString()))
            {
                Debug.Log("Right onDeviceDisConnected===>" + index);
                InputDataHandShank.HSData.HS1Connect = false;
                GetController(ControllerIndex.Right)?.gameObject.SetActive(false);

                GetController(index).inputDataHandShank.blueToothName = "K07";
                GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
                GetController(index).inputDataHandShank.isVaild = false;

                GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack -= updateRotationCallBack;
            }



        }
        else {
            GetController(index)?.gameObject.SetActive(false);
            if (index == ControllerIndex.Left)
                InputDataHandShank.HSData.HS0Connect = false;
            else
                InputDataHandShank.HSData.HS1Connect = false;

            GetController(index).inputDataHandShank.blueToothName = "K07";
            GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
            GetController(index).inputDataHandShank.isVaild = false;
            GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack -= updateRotationCallBack;

        }


        foreach ( var inputactionreference in listinput ) {
            inputactionreference.action.Disable();
            inputactionreference.action.performed -= OnInputPerformed;
            inputactionreference.action.canceled -= OnInputCanceled;
        }

        foreach ( var inputactionreference in listtrack ) {
            inputactionreference.action.Disable();
            inputactionreference.action.performed -= OnTrackPerformed;
            //inputactionreference.action.canceled -= OnTrackCanceled;
        }

    }
    private void onDeviceConnected(UnityEngine.XR.InputDevice obj)
    {
        if (Application.platform == RuntimePlatform.Android)
        {
            if (obj.characteristics.ToString().Contains(InputDeviceCharacteristics.Left.ToString()))
            {
                Debug.Log("Left onDeviceConnected===>" + index);
                InputDataHandShank.HSData.HS0Connect = true;
                GetController(ControllerIndex.Left)?.gameObject.SetActive(true);

                GetController(index).inputDataHandShank.blueToothName = "K07";
                GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
                GetController(index).inputDataHandShank.isVaild = true;


                GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack += updateRotationCallBack;
            }

            if (obj.characteristics.ToString().Contains(InputDeviceCharacteristics.Right.ToString()))
            {
                Debug.Log("Right onDeviceConnected===>" + index);
                InputDataHandShank.HSData.HS1Connect = true;
                GetController(ControllerIndex.Right)?.gameObject.SetActive(true);

                GetController(index).inputDataHandShank.blueToothName = "K07";
                GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
                GetController(index).inputDataHandShank.isVaild = true;


                GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack += updateRotationCallBack;
            }
        }
        else
        {
            GetController(index)?.gameObject.SetActive(true);
            if (index == ControllerIndex.Left)
                InputDataHandShank.HSData.HS0Connect = true;
            else
                InputDataHandShank.HSData.HS1Connect = true;

            GetController(index).inputDataHandShank.blueToothName = "K07";
            GetController(index).inputDataHandShank.handShankType = HandShankType.K07;
            GetController(index).inputDataHandShank.isVaild = true;

            GetController(index).inputDataGetHandShank.inputDataGetHandShank3DOF.updateRotationCallBack += updateRotationCallBack;
        }

        foreach ( var inputactionreference in listinput ) {
            inputactionreference.action.Enable();
            inputactionreference.action.performed += OnInputPerformed;
            inputactionreference.action.canceled += OnInputCanceled;
        }

        foreach ( var inputactionreference in listtrack ) {
            inputactionreference.action.Enable();
            inputactionreference.action.performed += OnTrackPerformed;
           // inputactionreference.action.canceled += OnTrackCanceled;
        }

    }

    public Quaternion controllerRotation { get; private set; }
    public Vector3 controllerPosition { get; private set; }

    void OnTrackPerformed(InputAction.CallbackContext context) {
        //Debug.Log(Time.frameCount+"  OnTrackPerformed" + index + " " + context.control.name);
        switch ( context.control.name ) {
            case "deviceposition":
            case "devicePosition":
                controllerPosition = context.ReadValue<Vector3>();
                break;
            case "devicerotation":
            case "deviceRotation":
                //Debug.Log(Time.frameCount + "  OnTrackPerformed" + index + " " + context.control.name+"  "+context.ReadValue<Quaternion>());
                // GetController(index).inputDataHandShank.rotation = context.ReadValue<Quaternion>();
                controllerRotation = context.ReadValue<Quaternion>();
                break;
        }
    }
    //private void OnTrackCanceled(InputAction.CallbackContext context) {
    //    Debug.Log("OnTrackCanceled" + index + " " + context.control.name);
    //    switch ( context.control.name ) {
    //        case "devicePosition":
    //            break;
    //        case "deviceRotation":
    //            GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);
    //            break;
    //    }
    //}

    void updateRotationCallBack() {
        Debug.Log(index+" updateRotationCallBack===>");
        GetController(index).inputDataHandShank.rotation = controllerRotation;//Quaternion.AngleAxis(20, transform.forward)* 
        GetController(index).inputDataHandShank.position = new Vector3( controllerPosition.x, controllerPosition.y+1, controllerPosition.z);
    }


    private void LateUpdate()
    {
        //Debug.Log("LateUpdate  " + GetController(index).inputDataHandShank.rotation);
        if (GetController(index))
        {
           // GetController(index).inputDeviceHandShankUI.transform.rotation = controllerRotation;
            //GetController(index).inputDeviceHandShankUI.model.lineIndicate.transform.rotation = controllerRotation;
            //if (GetController(index).inputDeviceUIBase)
            //{
            //    GetController(index).inputDeviceUIBase.BeforTargetDetecterUpdateUI();
            //}
            //if (GetController(index).inputDataProcessBase != null)
            //{
            //    GetController(index).inputDataProcessBase.OnUpdateAfterUI();
            //}
            ///û��UI��û��Ҫִ��TargetDecter�ı�Ҫ
            //if (GetController(index).inputDeviceUIBase != null && GetController(index).inputDeviceTargetDetecterBase != null)
            //{
            //    GetController(index).inputDeviceTargetDetecterBase.OnUpdate();
            //}

            //if (GetController(index).inputDeviceUIBase)
            //{
            //    GetController(index).inputDeviceUIBase.AfterTargetDetecterUpdateUI();
            //}
            //GetController(index).inputDeviceHandShankUI.modelK07.transform.rotation = controllerRotation;



            //if (GetController(index).inputDataBase != null)
            //{
            //    GetController(index).inputDataBase.OnUpdate();
            //}

            //if (GetController(index).inputDataGetBase != null)
            //{
            //    GetController(index).inputDataGetBase.OnUpdate();
            //}

            //GetController(index).inputDataHandShank.rotation = controllerRotation;
            //GetController(index).inputDataHandShank.position = controllerPosition;

            //if (GetController(index).inputDevicePartStatusBase != null)
            //{
            //    GetController(index).inputDevicePartStatusBase.OnUpdate();
            //}

            /////���������Ч�򲻿ɻ�ȡ����ر�UI���˳�
            //if (GetController(index).inputDataBase.isVaild == false)
            //{
            //    GetController(index).inputDeviceUIBase.UIDisable();
            //    DebugMy.Log("inputDataBase.isVaild == false ��Turn Off UI and Return", this);
            //    return;
            //}
            //else
            //{
            //    DebugMy.Log("inputDataBase.isVaild == true", this);
            //    GetController(index).inputDeviceUIBase.UIEnable();
            //}

            /////һЩUI����ֵˢ�±�����UI����ǰִ����
            //if (GetController(index).inputDataProcessBase != null)
            //{
            //    GetController(index).inputDataProcessBase.OnUpdateBeforUI();
            //}

            //if (GetController(index).inputDeviceUIBase)
            //{
            //    GetController(index).inputDeviceUIBase.BeforTargetDetecterUpdateUI();
            //}

            //if (GetController(index).inputDataProcessBase != null)
            //{
            //    GetController(index).inputDataProcessBase.OnUpdateAfterUI();
            //}

            /////û��UI��û��Ҫִ��TargetDecter�ı�Ҫ
            //if (GetController(index).inputDeviceUIBase != null && GetController(index).inputDeviceTargetDetecterBase != null)
            //{
            //    GetController(index).inputDeviceTargetDetecterBase.OnUpdate();
            //}

            //if (GetController(index).inputDeviceUIBase)
            //{
            //    GetController(index).inputDeviceUIBase.AfterTargetDetecterUpdateUI();
            //}            ///һЩUI����ֵˢ�±�����UI����ǰִ����
            //if (GetController(index) != null)
            //{
            //    GetController(index).inputDeviceUIBase.model.lineIndicate.DrawLineIndicate() ;
            //}


        }
    }

    int xy = 8;


    void OnInputPerformed(InputAction.CallbackContext context) {
        Debug.Log("OnInput================>" + index + " " + context.control.name);
        switch ( context.control.name ) {
            case "secondarytouched":
                break;
            case "secondarybutton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);

                break;
            case "primarytouched":
                break;
            case "primarybutton":

                break;
            case "touchpadtouched":
                break;
            case "thumbstickclicked":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Tp, InputKeyState.DOWN);
                break;
            case "thumbstick":
                GetController(index)?.inputDataHandShank.InputDataAddTouch(true,
                    new Vector2(xy + (int)(context.ReadValue<Vector2>().x * 10), xy + (int)(context.ReadValue<Vector2>().y * 10)));
                break;
            case "grip":

                break;
            case "grippressed":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);

                break;
            case "triggerpressed":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);
                break;
            case "menu":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Function, InputKeyState.DOWN);
                break;
            case "triggerButton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);
                break;
            case "gripButton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);
                break;


        }
    }
    private void OnInputCanceled(InputAction.CallbackContext context) {
        Debug.Log("OnInput================>" + index + " " + context.control.name);
        switch ( context.control.name ) {
            case "secondarytouched":
                break;
            case "secondarybutton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);

                break;
            case "primarytouched":
                break;
            case "primarybutton":

                break;
            case "touchpadtouched":
                break;
            case "thumbstickclicked":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Tp, InputKeyState.UP);
                break;
            case "thumbstick":
                GetController(index)?.inputDataHandShank.InputDataAddTouch(true,
                    new Vector2(xy + (int)(context.ReadValue<Vector2>().x * 10), xy + (int)(context.ReadValue<Vector2>().y * 10)));
                break;
            case "grip":

                break;
            case "grippressed":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);

                break;
            case "triggerpressed":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);
                break;
            case "menu":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Function, InputKeyState.UP);
                break;
            case "triggerButton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);
                break;
            case "gripButton":
                GetController(index)?.inputDataBase.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);
                break;
        }
    }

    public enum ControllerIndex { 
        Left = 0,
        Right = 1
    }
    InputDeviceHandShankPart GetController(ControllerIndex controllerIndex) {
        if ( SC.InputSystem.InputSystem.Instant && SC.InputSystem.InputSystem.Instant.HandShank ) {
            if ( ControllerIndex.Left == controllerIndex ) {
                return SC.InputSystem.InputSystem.Instant.HandShank.inputDeviceHandShankPartList.Where(e => e.PartType == SC.InputSystem.InputDevicePartType.HandShankOne).FirstOrDefault();
            } else if ( ControllerIndex.Right == controllerIndex ) {
                return SC.InputSystem.InputSystem.Instant.HandShank.inputDeviceHandShankPartList.Where(e => e.PartType == SC.InputSystem.InputDevicePartType.HandShankTwo).FirstOrDefault();
            }
        }
        return null;
    }





}