using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace laba3.Core
{
    /// <summary>
    /// TUI menu;
    /// </summary>
    internal class Menu
    {
        private List<Option> options;
        private int selected;
        private string title;
        
        /// <summary>
        /// Constructor of menu;
        /// </summary>
        /// <param name="title">Title of menu</param>
        public Menu(string title)
        {
            this.title = title;
            this.options = new List<Option> { };
        }

        /// <summary>
        /// Add option to menu;
        /// </summary>
        /// <param name="name">Name of option</param>
        /// <param name="action">Action, runs if option selected</param>
        public void AddOption(string name, Action action)
        {
            this.options.Add(new Option(name, action));
        }

        /// <summary>
        /// Run menu;
        /// Console will be clean!;
        /// </summary>
        public void RunMenu()
        {
            selected = 0;
            this.PrintMenu();
            ConsoleKeyInfo keyinfo;
            do
            {
                keyinfo = Console.ReadKey();

                if (keyinfo.Key == ConsoleKey.DownArrow)
                {
                    if (selected + 1 < options.Count)
                    {
                        selected++;
                        this.PrintMenu();
                    }
                }
                if (keyinfo.Key == ConsoleKey.UpArrow)
                {
                    if (selected > 0)
                    {
                        selected--;
                        this.PrintMenu();
                    }
                }
                if (keyinfo.Key == ConsoleKey.Enter)
                {
                    Console.Clear();
                    options[selected].Action.Invoke();
                }
            } while (keyinfo.Key != ConsoleKey.Enter);
        }
        private void PrintMenu()
        {
            Console.Clear();
            Console.WriteLine(title);
            int optionIndex = 0;
            foreach (Option option in options)
            {
                string pointer = optionIndex == selected ? " ->" : "   ";
                Console.WriteLine($"{pointer}{option.Name}");
                optionIndex++;
            }
        }

        private struct Option
        {
            public string Name { get; }
            public Action Action { get; }

            public Option(string name, Action action)
            {
                Name = name;
                Action = action;
            }
        }
    }
}