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

#if UNITY_EDITOR
using UnityEditor;

#endif

public partial class FallawayFloorChain : MonoBehaviour
{
    [SerializeField] private float _spacing;
    [SerializeField] private float _delay;
    [SerializeField] private bool _forwards;

    private readonly List<FallawayFloor> _segments = new List<FallawayFloor>();
    private bool _triggered;

    private void Start()
    {
        GetComponentsInChildren(_segments);
    }

    private void LateUpdate()
    {
        if (_triggered) return;
        
        for (int i = 0; i < _segments.Count; i++)
        {
            if (_segments[i].Falling)
            {
                StartCoroutine(FallCR());
                
                break;
            }
        }
    }

    private IEnumerator FallCR()
    {
        _triggered = true;

        var wait = new WaitForSeconds(_delay);
        
        if (_forwards)
        {
            for (int i = 0; i < _segments.Count; i++)
            {
                _segments[i].Fall();
                yield return wait;
            }
        }
        else
        {
            for (int i = _segments.Count - 1; i >= 0; i--)
            {
                _segments[i].Fall();
                yield return wait;
            }
        }

        yield return new WaitUntil(() =>
        {
            var idx = _forwards ? _segments.Count - 1 : 0;
            
            foreach (var segment in _segments)
            {
                if (segment.Falling) return false;
            }

            _triggered = false;

            if (!_segments[idx].Falling)
            {
                _triggered = false;
                return true;
            }
            
            return false;
        });
    }
}

#region Editor

#if UNITY_EDITOR

public partial class FallawayFloorChain
{
    [SerializeField] private GameObject _prefab;
    
    [Range(1,16)]
    [SerializeField] private int _length;

    public float EDITOR_Spacing => _spacing;
    public int EDITOR_Length => _length;
    
    public void EDITOR_Refresh()
    {
        if (_length == transform.childCount) return;

        for (int i = transform.childCount - 1; i >= 0; i--)
        {
            DestroyImmediate(transform.GetChild(i).gameObject);
        }

        _segments.Clear();
        for (int i = 0; i < _length; i++)
        {
            var platform = Instantiate(_prefab, transform).GetComponent<FallawayFloor>();
            _segments.Add(platform);
        }
        
        EDITOR_RefreshSpacing();
    }

    public void EDITOR_RefreshSpacing()
    {
        for (int i = 0; i < _segments.Count; i++)
        {
            _segments[i].transform.localPosition = Vector3.forward * _spacing * i;
        }
    }
}

[CustomEditor(typeof(FallawayFloorChain))]
public class FallawayFloorChainEditor : Editor
{
    private FallawayFloorChain _data;

    private void OnEnable()
    {
        _data = target as FallawayFloorChain;
    }

    public override void OnInspectorGUI()
    {
        var spacing = _data.EDITOR_Spacing;
        
        base.OnInspectorGUI();

        if (_data.transform.childCount != _data.EDITOR_Length)
        {
            _data.EDITOR_Refresh();
        }

        if (spacing != _data.EDITOR_Spacing)
        {
            _data.EDITOR_RefreshSpacing();
        }
    }
}

#endif

#endregion