using JetBrains.Annotations;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public class DragCanon : MonoBehaviour
{
    private Vector2 initialOffset;
    private bool dragging;
    private GameObject oldCell;

    [SerializeField] private float planeHeight = 0; // Set to canon Y pos
    [SerializeField] private float mergeThreshold;

    GridCell[] allCells;

    private Vector3 offset;

    private GameManager gameManager;

    private void Start()
    {
        allCells = FindObjectsByType<GridCell>(FindObjectsSortMode.None);
        oldCell = gameObject.GetComponent<CanonController>().GetCurrentCell();
        initialOffset = transform.position - GetClosestCell().transform.position;
        dragging = false;
        planeHeight = transform.position.y;
        gameManager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManager>();
    }

    void OnMouseDown()
    {
        if (Camera.main == null) return;

            offset = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - (Vector2)transform.position;
            //Debug.Log(offset);
            dragging = true;
    }

    private void OnMouseDrag()
    {

            Drag_Canon();

    }


    void Drag_Canon()
    {
        transform.position = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - (Vector2)offset;
    }


    void SnapToNewCell()
    {
        GameObject closestCell = GetClosestCell();

        //if (closestCell.GetComponent<GridCell>().IsOccupied())
        //{
        //    Debug.Log(closestCell.transform.position);
        //    Debug.Log("Canons: " + CanonPlacementManager.instance.GetCanonCount());
        //    Debug.Log("Is Occupied");


        if (closestCell != oldCell)
        {
            if (closestCell.GetComponent<GridCell>().IsOccupied())
            {                
                GameObject canonOnClosestCell = closestCell.GetComponent<GridCell>().GetCanonOnCell();
                if (canonOnClosestCell == null)
                {
                    Debug.Log("no canon found");
                    return;
                }

                if (canonOnClosestCell.GetComponent<CanonController>().GetCanonStage() == gameObject.GetComponent<CanonController>().GetCanonStage())
                {
                    Destroy(canonOnClosestCell);
                    MergeCanon(closestCell);
                }
                else
                {
                    GoToUnoccupiedCell();
                }
            }
            else
            {
                GoToUnoccupiedCell();
            }
        }
        else
        {
            gameObject.GetComponent<Transform>().position = gameObject.GetComponent<CanonController>().GetCurrrentCellPosition();
        }

    }

    void GoToUnoccupiedCell()
    {
        GameObject cell = GetClosestUnOccupiedCell();
        if (cell == null) 
        {
            Debug.Log("no cell unoccupied");
        }
        oldCell.GetComponent<GridCell>().UnOccupy();
        oldCell = cell;
        cell.GetComponent<GridCell>().RelocateMachineGun(gameObject);
    }

    void MergeCanon(GameObject cell)
    {
        oldCell.GetComponent<GridCell>().UnOccupy();
        oldCell = cell;
        oldCell.GetComponent<GridCell>().RelocateMachineGun(gameObject);
        gameObject.GetComponent<CanonController>().IncrementCanonStage();
        CanonPlacementManager.instance.DecrementCanonCount();
    }

    void OnMouseUp()
    {
            //Debug.Log("dragging: " + dragging);
            if (dragging)
            {
                dragging = false;
                //Debug.Log(dragging);
                SnapToNewCell();
            }
    }

    GameObject GetClosestCell()
    {
        if (allCells == null)
        {
            return null;
        }

        if (allCells.Length == 0)
        {
            return null;
        }

        GameObject closestCell = allCells[0].GameObject();
        foreach (GridCell cell in allCells)
        {
            if (IsCloser(cell.GameObject(), closestCell))
            {
                closestCell = cell.GameObject();
            }
        }
        return closestCell;
    }

    GameObject GetClosestUnOccupiedCell()
    {
        if (allCells.Length == 0)
            return null;

        GameObject closestCell = allCells[0].GameObject();
        foreach (GridCell cell in allCells)
        {
            if (!cell.GetComponent<GridCell>().IsOccupied())
                closestCell = cell.GameObject();
        }

        foreach (GridCell cell in allCells)
        {
            if (IsCloser(cell.GameObject(), closestCell) && !cell.GetComponent<GridCell>().IsOccupied())
            {
                closestCell = cell.GameObject();
            }
        }
        return closestCell;
    }


    //CanonController GetCanonWithinThreshold(float threshold)
    //{
    //    return null;
    //}

    bool IsCloser(GameObject cell, GameObject currentClosest)
    {
        bool closer = Mathf.Abs(Vector3.Distance(cell.GetComponent<Transform>().position, transform.position)) < Mathf.Abs(Vector3.Distance(currentClosest.GetComponent<Transform>().position, transform.position));
        //Debug.Log(closer);
        return closer;
    }

}