using FOHEART.GlovePlugin;
using System.Collections.Generic;
using UnityEngine;

public class GrabItemLogic : FOGestureActionAdatper
{

    public override void onLeftHandGesture(Gesture currentGesture, GameObject leftHandTouchObject, GameObject gameObject)
    {
        setAdjacentItem(gameObject);

        // ץȡƷ
        if (currentGesture == Gesture.GRAB_ITEM)
        {
            if (adjacentItem != null && Time.time - adjacentItemTouchedTime <= 0.3f)
            {
                CancelInvoke(nameof(resetItemKinematic));

                adjacentItemTouchedTime = lastGrabItemTime = Time.time;

                // ȡRigidbody
                Rigidbody rigidBody = adjacentItem.GetComponent<Rigidbody>();
                if (rigidBody != null)
                {
                    // isKinematicΪtrueʱ
                    rigidBody.isKinematic = true;
                }
                Vector3 newPos = leftHandTouchObject.transform.position;
                newPos.x -= 0.01f;
                newPos.y += 0.03f;
                adjacentItem.transform.position = newPos;
                adjacentItem.transform.rotation = leftHandTouchObject.transform.rotation;
            }
        }
        // 
        else if (currentGesture == Gesture.DEPART)
        {
            //
            if (adjacentItem != null && Time.time - lastGrabItemTime <= 0.3f)
            {
                CancelInvoke(nameof(resetItemKinematic));

                if (adjacentItem.GetComponents<Rigidbody>().Length == 0)
                {
                    flyingObj = adjacentItem;
                    adjacentItem = null;

                    flyingObj.transform.position = itemStartFlyingPoint.position;
                    flyingObj.transform.rotation = itemStartFlyingPoint.rotation;

                    isItemFlyingFlag = true;

                    lastGrabItemTime = 0f;
                }
                else
                {
                    isItemFlyingFlag = false;
                    resetItemKinematic();
                    adjacentItem.GetComponent<Rigidbody>().AddForce(itemStartFlyingPoint.forward, ForceMode.Impulse);
                }
            }
        }
        // ӵ
        else if (currentGesture == Gesture.BULLET)
        {
            handleBulletGesture();
        }
        // 
        else if (currentGesture == Gesture.FIRE)
        {
            handleFireGesture();
        }


        // ٴж
        if (currentGesture == Gesture.GRAB_ITEM)
        { }
        else
        {
            // ץ״̬ץʱ
            adjacentItemTouchedTime = 0;
            // 
            Invoke(nameof(resetItemKinematic), 0.4f);
        }
    }

    int itemKinematicKey = 0;

    private void resetItemKinematic()
    {
        if (adjacentItem == null)
        {
            return;
        }

        // ȡRigidbody
        if (itemKinematicKey > 0)
        {
            adjacentItem.GetComponent<Rigidbody>().isKinematic = (itemKinematicKey == 1);
            itemKinematicKey = 0;
        }
    }

    public Transform itemStartFlyingPoint;

    private GameObject flyingObj = null;
    private bool isItemFlyingFlag = false;

    private void FixedUpdate()
    {
        if (isItemFlyingFlag) // Ƿ񱻒С
        {
            // ʹ++ -- ģɳ
            flyingObj.transform.Translate(0f, -0.01f, 0.005f, Space.Self);
            // Сֵָ˶
            if (flyingObj.transform.position.y < 0.05)
            {
                if (itemKinematicKey > 0)
                {
                    flyingObj.GetComponent<Rigidbody>().isKinematic = (itemKinematicKey == 1);
                }
                isItemFlyingFlag = false;
                flyingObj = null;
            }
        }
    }


    [Tooltip("ӵģ")]
    public GameObject bulletPrefab;
    [Tooltip("Уӵʼλ")]
    public Transform bulletInitTransform;
    // ǰӵ
    private GameObject currentBullet = null;

    [Tooltip("(߶ģ)Ⱦ")]
    public LineRenderer rayLine;
    [Tooltip("(߶ģ)ʼλê")]
    public GameObject rayLineAnchorObj;

    public override LineRenderer getRayLine()
    {
        return rayLine;
    }

    public override GameObject getRayLineAnchorObj()
    {
        return rayLineAnchorObj;
    }

    private void handleBulletGesture()
    {
        // ϴ
        CancelInvoke("hideBullet");
    
        if (currentBullet != null)
        {
            Debug.Log("currentBullet ---------");
            currentBullet.transform.position = bulletInitTransform.position;
            currentBullet.transform.rotation = bulletInitTransform.rotation;

            Invoke(nameof(hideBullet), 1f);

            return;
        }

        // ʼӵ
        currentBullet = Instantiate(bulletPrefab, bulletInitTransform);
        currentBullet.transform.position = bulletInitTransform.position;
        currentBullet.transform.rotation = bulletInitTransform.rotation;

        Debug.Log("currentBullet " + (currentBullet==null));

        Invoke(nameof(hideBullet), 1f);
    }
    
    private void handleFireGesture()
    {
        GameObject targetObj = null;
        GameObject bullet = currentBullet;
    
        if (currentBullet != null)
        {
            // ϴ
            CancelInvoke("hideBullet");
    
            // (߶ģ)ʼλü
            Vector3 anchorV3 = getRayLineAnchorObj().transform.position;
            Vector3 fwd3 = getRayLineAnchorObj().transform.forward;
            // ִ߼
            if (Physics.Raycast(anchorV3, fwd3, out RaycastHit raycastHit, 20000f))
            {
                targetObj = raycastHit.collider.gameObject;
            }
    
            // ӵ
            currentBullet.transform.SetParent(null);

            // ӵ
            BulletMoveForwardLogic fwdLogic = currentBullet.GetComponent<BulletMoveForwardLogic>();
            fwdLogic.activeItem();
    
            currentBullet = null;
        }
    }


    private void hideBullet()
    {
        if (currentBullet != null)
        {
            currentBullet.transform.Translate(100000f, 100000f, 100000f);
        }
    }

    /// <summary>
    /// ִ
    /// </summary>
    private GameObject adjacentItem = null;
    /// <summary>
    /// ִʱ
    /// </summary>
    private float adjacentItemTouchedTime = 0f;
    /// <summary>
    /// ץʱ
    /// </summary>
    private float lastGrabItemTime = 0f;
    ////// <summary>
    ////// isKinematicʼֵ
    ////// </summary>
    ///private Dictionary<GameObject, bool> grableItemKinematicMap = new Dictionary<GameObject, bool>();

    private void setAdjacentItem(GameObject item)
    {
        if (item == null)
        {
            return;
        }

        // жǷ GrabHoldFlag ־
        int length = item.GetComponentsInParent(typeof(GrabHoldFlag)).Length;
        if (length == 0)
        {
            //  GrabHoldFlag ־ץ
            return;
        }

        // ֮ǰץչ壬ٴδ壬δɿ֮ǰ
        if (adjacentItem != null && item != adjacentItem && adjacentItemTouchedTime > 0f)
        {
            return;
        }

        // ǰδץκ
        adjacentItem = item;
        adjacentItemTouchedTime = Time.time;

        // ȡRigidbody
        if (itemKinematicKey == 0 && item.GetComponents(typeof(Rigidbody)).Length > 0)
        {
            // ¼isKinematicֵ
            bool isItemKinematic = item.GetComponent<Rigidbody>().isKinematic;
            itemKinematicKey = isItemKinematic ? 1 : 2;
        }

        ///if (lastAdjacentItem != adjacentItem && lastAdjacentItem != null)
        ///{
        ///    if (lastAdjacentItem.GetComponents(typeof(Rigidbody)).Length > 0)
        ///    {
        ///        bool isKinematic = grableItemKinematicMap.ContainsKey(lastAdjacentItem);
        ///        ///// isKinematicΪtrueʱ
        ///        lastAdjacentItem.GetComponent<Rigidbody>().isKinematic = isKinematic ? grableItemKinematicMap[lastAdjacentItem] : false;
        ///    }
        ///}
        ///lastAdjacentItem = adjacentItem;
    }

}
