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

namespace PlantBox.Broker
{
    class Broker
    {
        public PlantBoxesManager PlantBoxesManager { get; }
        public ClientManager ClientManager { get; }
        public ServerManager ServerManager { get; }

        public bool IsRunning { get; set; } = true;

        private Timer _autoSaveTimer;

        public Broker(string[] args)
        {
            Console.WriteLine("Initializing Broker...");

            PlantBoxesManager = new PlantBoxesManager();

            PlantBoxesManager.Load();
            PlantBoxesManager.UpdatePlantsState();

            ClientManager = new ClientManager(this);
            ServerManager = new ServerManager(this);
        }

        public void Start()
        {
            Task.Run(() => ClientManager.Start());
            Task.Run(() => ServerManager.Start());

            // Auto-Save
            _autoSaveTimer = new Timer(OnSave, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));

            string input;
            do
            {
                input = Console.ReadLine().ToLowerInvariant();

                string[] split = input.Split(" ");
                input = split[0];
                string[] args = split.Skip(1).ToArray();

                ExeCommand(input.ToLower(), args);
            } while (input != "exit" && input != "stop" && input != "quit");

            Console.WriteLine("Stopping Broker...");

            IsRunning = false;
            _autoSaveTimer.Dispose();
            PlantBoxesManager.Save();
        }

        private void OnSave(object state)
        {
            PlantBoxesManager.Save();
        }

        private void ExeCommand(string command, string[] arguments)
        {
            switch (command)
            {
                case "save":
                    PlantBoxesManager.Save();
                    break;
                case "clear":
                    Console.WriteLine($"Clearing {arguments[0]}...");
                    if (ulong.TryParse(arguments[0], out ulong id) && PlantBoxesManager[id] != null)
                    {
                        PlantBoxesManager.ClearPlantBox(PlantBoxesManager[id]);
                        Console.WriteLine($"{id} cleared");
                    }
                    else
                    {
                        Console.WriteLine("Invalid id");
                    }
                    break;
                case "list":
                    foreach (var plant in PlantBoxesManager)
                    {
                        Console.WriteLine(plant);
                    }
                    break;
            }
        }
    }
}
