using System;
using System.Collections.Generic;
using Roads;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;

namespace Routes
{
    [Serializable]
    public struct RouteItem
    {
        public Turn turn;
        public RoadDirection from;
        public RoadDirection to;

        public void Apply()
        {
            if (turn.comingFrom != from || turn.goingTo != to)
            {
                turn.comingFrom = from;
                turn.goingTo = to;
                turn.UpdateArrows();
            }
        }

        public void Clear()
        {
            if (turn.comingFrom != RoadDirection.None || turn.goingTo != RoadDirection.None)
            {
                turn.comingFrom = RoadDirection.None;
                turn.goingTo = RoadDirection.None;
                turn.UpdateArrows();
            }
        }
    }

    public class Route : MonoBehaviour
    {
        public List<RouteItem> items;

        public StraightRoadExtras start;
        public StraightRoadExtras finish;

        private int visibleLength;
        private int visibleStart;

        private int VisibleStart => Math.Max(0, visibleStart - 1);

        private int VisibleEnd => Math.Min(items.Count, VisibleStart + visibleLength);

        public delegate void OnStartEnteredEvent();

        public event OnStartEnteredEvent OnStartEntered;
        
        public delegate void OnFinishPassedEvent();

        public event OnFinishPassedEvent OnFinishPassed;

        private void Start()
        {
            start.ShowArc();
            SetupEvents();

            var routeManager = GetComponentInParent<RouteManager>();
            visibleStart = 0;
            visibleLength = routeManager.visibleLength;

            items.ForEach((item) => item.turn.OnTriggerExitBicycle = NextTurn);
            UpdateRouteItems();
        }

        private void SetupEvents()
        {
            start.OnArcEntered += () =>
            {
               OnStartEntered?.Invoke();
            };
            finish.OnArcPassed += () =>
            {
                OnFinishPassed?.Invoke();
            };
        }

        private void NextTurn()
        {
            Debug.Log("Route: left intersection - show next turn");
            visibleStart++;
            UpdateRouteItems();
        }

        private void UpdateRouteItems()
        {
            if (VisibleEnd == items.Count - 1)
            {
                finish.ShowArc();
            }

            for (var i = 0; i < VisibleEnd; i++)
            {
                var item = items[i];
                if (i >= VisibleStart)
                {
                    item.Apply();
                }
                else
                {
                    item.Clear();
                }
            }
        }
    }
}