using UnityEngine;
using UnityEngine.EventSystems;

public class BuilderManager : MonoBehaviour
{
    [SerializeField] private GameObject buildingsParent;
    [SerializeField] private AudioClipGroup placeSound;

    public bool IsFree { get; private set; }
    private bool isBuilding;
    private BuildingData selectedBuilding;
    private GameObject preview;
    private SpriteRenderer previewSpriteRenderer;

    private void Awake()
    {
        isBuilding = false;
        Events.OnBuildingSelected += OnBuildingSelected;
    }

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

    private void FixedUpdate()
    {
        //Updating position in fixedUpdate to fix a bug when moving mouse fast you could build buildings in other buildings
        if (isBuilding) UpdatePosition();
    }

    public void UpdateColor()
    {
        if (isBuilding)
        {
            IsFree = IsAreaAvailableForBuilding();
            previewSpriteRenderer.color = IsFree ? Color.green : Color.red;
        }
    }

    public void DeselectBuilding()
    {
        Destroy(preview);
        isBuilding = false;
        Events.BuildingDeselected();
    }

    public void Place()
    {
        if (EventSystem.current.IsPointerOverGameObject() || !IsAreaAvailableForBuilding()) return;

        placeSound.Play();
        CameraMovement.Instance.CameraShake();

        Vector3 pos = new(
            preview.transform.position.x,
            preview.transform.position.y,
            0);

        GameObject building = Instantiate(selectedBuilding.BuildingPrefab, pos, Quaternion.identity, buildingsParent.transform);
        Building build = building.GetComponent<Building>();
        build.Initiate(selectedBuilding);
        MapManager.Instance.NewBuildingPlaced(build.transform.position, build.BuildingData);

    }

    private void UpdatePosition()
    {
        Vector3 mousePosition = Input.mousePosition;

        float clampedX = Mathf.Clamp(mousePosition.x, 0f, Screen.width);
        float clampedY = Mathf.Clamp(mousePosition.y, 0f, Screen.height);

        mousePosition = new(clampedX, clampedY, mousePosition.z);

        Vector3 pos = Camera.main.ScreenToWorldPoint(mousePosition);

        // Snap to grid based on building size
        float xOffset = 0.5f * selectedBuilding.Size.x;
        float yOffset = 0.5f * selectedBuilding.Size.y;
        pos.Set(Mathf.Round(pos.x - xOffset) + xOffset, Mathf.Round(pos.y - yOffset) + yOffset, -2);

        preview.transform.position = pos;
    }

    private void OnBuildingSelected(BuildingData selectedBuilding)
    {
        if (!GameManager.Instance.GameIsOn) return;

        this.selectedBuilding = selectedBuilding;
        if (preview != null) Destroy(preview);

        preview = Instantiate(selectedBuilding.BuildingPrefab, transform.parent);
        previewSpriteRenderer = preview.GetComponent<SpriteRenderer>();

        UpdatePosition();
        isBuilding = true;
    }

    private bool IsAreaAvailableForBuilding()
    {
        // Checks if the buildig ground is available
        return MapManager.Instance.CheckIfAvailableForBuilding(
            preview.transform.position, 
            selectedBuilding
            );
    }
}
