using Unity.VisualScripting.Antlr3.Runtime.Tree;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(BuilderManager))]
public class BuildingsInteractionManager : MonoBehaviour
{
    [SerializeField] private LayerMask overlapLayer;
    [SerializeField] private Button demolishButton;
    [SerializeField] private SpriteRenderer outline;
    [SerializeField] private AudioClipGroup demolishSound;

    public LayerMask OverlapLayer { get => overlapLayer; }

    private CursorState cursorState;
    public CursorState CursorState 
    { 
        get => cursorState;  
        private set
        {
            cursorState = value;
            if (cursorState == CursorState.Free)
                MapManager.Instance.DisplayBuildArea(false);
            else
                MapManager.Instance.DisplayBuildArea(true);
        }
    }

    private BuilderManager builderManager;
    private CardMovingManager cardMovingManager;

    private GameObject highlighted;

    private void Awake()
    {
        builderManager = GetComponent<BuilderManager>();
        cardMovingManager = GetComponent<CardMovingManager>();

        demolishButton.onClick.AddListener(() =>
            CursorState = CursorState == CursorState.Free ? CursorState.Demolishing : CursorState.Free
            );

        Events.OnBuildingSelected += OnBuildingSelected;
        Events.OnBuildingDeselected += OnBuildingDeselected;
        Events.OnCardForMovingSelected += OnCardForMovingSelected;

        Events.OnDayEnd += OnDayEnd;
    }

    private void OnDestroy()
    {
        Events.OnBuildingSelected -= OnBuildingSelected;
        Events.OnBuildingDeselected -= OnBuildingDeselected;
        Events.OnCardForMovingSelected -= OnCardForMovingSelected;

        Events.OnDayEnd += OnDayEnd;
    }

    private void OnBuildingSelected(BuildingData _) => CursorState = CursorState.Building;
    private void OnBuildingDeselected() => CursorState = CursorState.Free;
    private void OnCardForMovingSelected(Building _, Card __)
    {
        if (CursorState == CursorState.Free)
        {
            CursorState = CursorState.MovingCard;
        }
    }

    private void OnDayEnd()
    {
        if (cursorState == CursorState.Building)
            builderManager.DeselectBuilding();
        CursorState = CursorState.Free;
    }

    private void Update()
    {
        outline.enabled = false;
        if (highlighted != null)
        {
            highlighted.GetComponent<SpriteRenderer>().color = Color.white;
            highlighted = null;
        }

        // Finds if there's a building under the cursor
        Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast(mousePosition, Vector2.zero, Mathf.Infinity, overlapLayer);

        if (!EventSystem.current.IsPointerOverGameObject() && hit.collider != null)
        {
            if (!hit.collider.CompareTag("start build"))
            {
                highlighted = hit.collider.gameObject;
            }
        }

        switch (CursorState)
        {
            case CursorState.Building:
                CursorBuilding();
                break;
            case CursorState.Demolishing:
                CursorDemolishing();
                break;
            case CursorState.MovingCard:
                CursorMovingCard();
                break;
            default:
                break;
        }
    }

    private void CursorBuilding()
    {
        builderManager.UpdateColor();

        if (Input.GetKeyDown(KeyCode.Mouse1))
            builderManager.DeselectBuilding();
        else if (Input.GetKeyDown(KeyCode.Mouse0) && builderManager.IsFree)
            builderManager.Place();
    }

    private void CursorMovingCard()
    {
        if (cardMovingManager.IsMovingCard && Input.GetKeyUp(KeyCode.Mouse0))
        {
            cardMovingManager.Place();
            CursorState = CursorState.Free;
        }
    }

    private void CursorDemolishing()
    {
        if (highlighted != null && IsTopOpen())
        {
            highlighted.GetComponent<SpriteRenderer>().color = Color.yellow;

            if (highlighted.TryGetComponent(out Building building) && building.BuildingData != null)
            {
                outline.size = building.BuildingData.Size + new Vector2(0.25f, 0.25f);
                outline.transform.position = new(
                    highlighted.transform.position.x,
                    highlighted.transform.position.y,
                    outline.transform.position.z);
                outline.enabled = true;
            }

            if (Input.GetKeyDown(KeyCode.Mouse0))
            {
                demolishSound.Play();
                Building buildingToDemolish = highlighted.GetComponent<Building>();
                MapManager.Instance.RemoveBuilding(buildingToDemolish.transform.position, buildingToDemolish.BuildingData);
                buildingToDemolish.Demolish();
            }

        }
        else if (Input.GetKeyDown(KeyCode.Mouse0) || Input.GetKeyDown(KeyCode.Mouse1))
        {
            CursorState = CursorState.Free;
        }

        bool IsTopOpen()
        {
            BuildingData selectedBuilding = highlighted.GetComponent<Building>().BuildingData;
            return MapManager.Instance.CheckIfBuildingTopIsOpen(highlighted.transform.position, selectedBuilding);
        }
    }
    
}
