using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum GridTypes
{
    Son,
    Parent,
    Empty
}

public class CuadradoRaices : Nodo
{
    public Transform[] entries;
    float distanceToDetectArround = 0.2f;
    public Nodo[] objectsArround;
    TailRootManeger m_TailManager;
    LevelController m_LevelController;

    public ParticleSystem RootPlaced_particles;

    void Start()
    {
        m_LevelController = GameObject.FindGameObjectWithTag("LevelController").GetComponent<LevelController>();
        m_Collider2D = GetComponent<Collider2D>();
        m_TailManager = GetComponent<TailRootManeger>();
        objectsArround = new Nodo[4];
        GetArroundZones();

        entriesType = new GridTypes[4];
        SetTypesEntries();
        UpdateGraphics();
    }

    private void SetTypesEntries()
    {
        entriesType[0] = GridTypes.Empty;
        entriesType[1] = GridTypes.Empty;
        entriesType[2] = GridTypes.Empty;
        entriesType[3] = GridTypes.Empty;

        if (objectsArround[0] != null)
        {
            if (objectsArround[0].gameObject.tag == ("Plant"))
            {
                PutRoot(0);                
            }
        }
    }

    private void GetArroundZones()
    {
        m_Collider2D.enabled = false;
        RaycastHit2D _hit0;
        RaycastHit2D _hit1;
        RaycastHit2D _hit2;
        RaycastHit2D _hit3;
        _hit0 = Physics2D.Raycast(entries[0].position, new Vector2(0f, 1f), distanceToDetectArround);
        if (_hit0.collider != null)
        {
            objectsArround[0] = _hit0.collider.GetComponent<Nodo>();
        }
        else
        {
            objectsArround[0] = null;
        }
        _hit1 = Physics2D.Raycast(entries[1].position, new Vector2(-1f, 0f), distanceToDetectArround);
        if (_hit1.collider != null)
        {
            objectsArround[1] = _hit1.collider.GetComponent<Nodo>();
        }
        else
        {
            objectsArround[1] = null;
        }
        _hit2 = Physics2D.Raycast(entries[2].position, new Vector2(0f, -1f), distanceToDetectArround);
        if (_hit2.collider != null)
        {
            objectsArround[2] = _hit2.collider.GetComponent<Nodo>();
        }
        else
        {
            objectsArround[2] = null;
        }
        _hit3 = Physics2D.Raycast(entries[3].position, new Vector2(1f, 0f), distanceToDetectArround);
        if (_hit3.collider != null)
        {
            objectsArround[3] = _hit3.collider.GetComponent<Nodo>();
        }
        else
        {
            objectsArround[3] = null;
        }
        m_Collider2D.enabled = true;
    }

    void OnMouseDown()
    {
        if (Manager.Instance.StillPlaying())
        {
            if (CanPutRoot())
            {
                TryPutRoot();
            }
            else if (m_Parent != null)
            {
                PutTileBlink();

                //Root selection sound
                FMODUnity.RuntimeManager.PlayOneShot("event:/Root/Root_select");

                Manager.Instance.SetSelectionMode(this);
            }
        }
    }
    public void PutTileBlink()
    {
        int d = 0;
        int i = 0;
        GameObject[] tilesToBlink = new GameObject[3];
        foreach (GridTypes gt in entriesType)
        {
            if (gt == GridTypes.Empty)
            {
                if (objectsArround[i] != null)
                {
                    if (objectsArround[i].m_Parent == null && objectsArround[i].tag != ("supply"))
                    {
                        tilesToBlink[d] = objectsArround[i].gameObject;
                        d++;
                    }
                }
            }
            i++;
        }

        Manager.Instance.SetTilesBlink(tilesToBlink[0], tilesToBlink[1], tilesToBlink[2]);
    }

    private void OnMouseOver()
    {
        if (Manager.Instance.StillPlaying() && Input.GetMouseButtonDown(1) && m_Parent != m_PlantsController)
        {
            RemoveRoot(true);
        }
    }

    public override void RemoveRoot(bool first)
    {
        m_LevelController.numRoot--;
        entriesType[0] = GridTypes.Empty;
        entriesType[1] = GridTypes.Empty;
        entriesType[2] = GridTypes.Empty;
        entriesType[3] = GridTypes.Empty;
        if (first) (m_Parent as CuadradoRaices).RemoveChild((m_WhereIsParent + 2) % 4);
        UpdateGraphics();
        m_PlantsController = null;
        m_Parent.OnRemove -= RemoveRoot;
        m_Parent = null;
        m_WhereIsParent = 0;
        OnRemove?.Invoke(false);

        //Root remove sound
        FMODUnity.RuntimeManager.PlayOneShot("event:/Root/Root_delete");
    }

    public void RemoveChild(int childIdx)
    {
        entriesType[childIdx] = GridTypes.Empty;
        Manager.Instance.SetSelectionMode(this);
        UpdateGraphics();
        Manager.Instance.DestroyTileBlink();
        StartCoroutine(WaitPutTileBlink());
    }
    IEnumerator WaitPutTileBlink()
    {
        yield return new WaitForSeconds(0.1f);
        PutTileBlink();
    }
    private void TryPutRoot()
    {
        for (int i = 0; i < 4; i++)
        {
            if (objectsArround[i] != null)
            {
                if (objectsArround[i] == Manager.Instance.lastRootSelected)
                {
                    PutRoot(i);
                    return;
                }
            }
        }
    }

    private void PutRoot(int idx)
    {
        //Root created effects
        if (m_LevelController.numRoot > 0)
        {
            RootPlaced_particles.Play();
            FMODUnity.RuntimeManager.PlayOneShot("event:/Root/Root_place");
        }

        m_LevelController.numRoot++;
        m_Parent = objectsArround[idx].GetComponent<Nodo>();
        entriesType[idx] = GridTypes.Parent;
        m_PlantsController = m_Parent.m_PlantsController;
        m_WhereIsParent = idx;
        m_Parent.entriesType[(idx + 2) % 4] = GridTypes.Son;
        Manager.Instance.SetSelectionMode(this);
        UpdateGraphics();
        m_PlantsController.OnColorChange += UpdateGraphics;
        if (m_Parent is CuadradoRaices) (m_Parent as CuadradoRaices).UpdateGraphics();
        m_Parent.OnRemove += RemoveRoot;
        if (Manager.Instance.readyToPlay) PutTileBlink();

    }

    public void UpdateGraphics()
    {
        m_TailManager.SetTileSprite();
    }

    private bool CanPutRoot()
    {
        if (m_LevelController.numRoot < m_LevelController.maxRoot)
        {
            if (m_Parent != null) return false;

            int _rocks = 0;
            foreach (Nodo obj in objectsArround)
            {
                if (obj != null)
                {
                    if (obj.tag == ("Rock"))
                    {
                        _rocks++;
                    }
                }
            }
            if (_rocks >= 3)
            {
                return false;
            }

            return true;
        }
        else { return false; }
    }
}

