using Microsoft.AspNetCore.Mvc;
using System;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;

namespace SE290A_BackOfficeSim_CoreApi.Controllers
{
    public enum ButtonEventAction : byte
    {
        NoAction = 0,
        ShowNextPage = 1,
        ShowPrevPage = 2,
        ShowPageX = 3,
        ShowDefaultImage = 4,
        RefreshImage = 5,
        InvertImage = 6,
        TurnOffLed = 7,
        TurnOnLed = 8,
        Disabled = 9,
    }

    [Flags]
    public enum EslLedColor
    {
        None = 0x00,
        Red = 0x01,
        Green = 0x02,
        Blue = 0x04,
        Orange = 0x03,
        Magenta = 0x05,
        Cyan = 0x06,
        White = 0x07
    }

    [Route("api")]
    [ApiController]
    [Produces("application/xml")]
    public class InputController : ControllerBase
    {
        // GET input/info (also route for default connection)
        [HttpGet(""), Route("default")]
        public EslServerApiObject Info()
        {
            return new EslServerApiObject("", null, "SE-290A BackOffice Simulation Version: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " (" + DatabaseHelper.SqlDatabase + ")");
        }

        // GET input/keep-alive
        [HttpGet("KEEP-ALIVE")]
        public EslServerApiObject KeepAlive()
        {
            return new EslServerApiObject("", null, "Keep-alive");
        }

        [HttpGet("{Mac}/{Product_Id}/{Event}/{Value}/{SeqNr}/{Description}")]
        public EslServerApiObject GetProcessFromEslServer(string Mac, string Product_Id, string Event, string Value, string SeqNr, String Description)
        {
            return process_from_esl_server(Mac, Product_Id, Event, Value, SeqNr, Description, "GET");
        }

        // POST values
        [HttpPost("{Mac}/{Product_Id}/{Event}/{Value}/{SeqNr}/{Description}")]
        public EslServerApiObject ProcessFromEslServer(string Mac, string Product_Id, string Event, string Value, string SeqNr, String Description)
        {
            return process_from_esl_server(Mac, Product_Id, Event, Value, SeqNr, Description, null);
        }
                
        private EslServerApiObject process_from_esl_server(string ESL, string ProductId, string Event, string Value, string SeqNr, string Description, String Method = "POST")
        {
            MAC_Address MAC = new MAC_Address(ESL);

            string SequenceNumber = SeqNr.Substring(0, 8);

            bool SeqNrOK = true;

            EslImageInfo EslInfo;

            if (Program.LabelStatus.ContainsKey(ESL))
            {
                EslInfo = Program.LabelStatus[ESL];
            }
            else
            {
                EslInfo = new EslImageInfo(ESL);
                Program.LabelStatus.Add(ESL, EslInfo);
            }


            if (EslInfo.SeqNr != null && SequenceNumber.Equals(EslInfo.SeqNr))  // If same SeqNr, then replay the same result
            {
                SeqNrOK = false;
                EslInfo.Message = "OK";
            }
            else if (EslInfo.SeqNr != null && SequenceNumber.CompareTo(EslInfo.SeqNr) < 0 && !SequenceNumber.Substring(0, 4).Equals("0001") && DatabaseHelper.DbFormat != DBaseType.SQLite)
            {
                EslInfo.Message = "Invalid Sequence number";
                EslInfo.SeqNr = "00010001";
                SeqNrOK = false;
            }
            else
            {
                EslInfo.Message = "OK";
                EslInfo.SeqNr = SequenceNumber;
            }

            if (SeqNrOK)
            {
                EslInfo.Online = 1;
                EslInfo.Event = Event;
                EslInfo.Value = Value;
                EslInfo.Id = ProductId;
                EslInfo.Event = Event;

                if (!string.IsNullOrEmpty(Description))
                    EslInfo.Description = Description;

                if (DatabaseHelper.UpdateLabelStatus(EslInfo, DatabaseHelper.DbFormat == DBaseType.SQLite) || !EslInfo.Message.Equals("OK"))
                {
                    if (EslInfo.Message.Equals("OK"))
                    {
                        switch (Event)
                        {
                            case "PRESSED": Console.ForegroundColor = ConsoleColor.Magenta; break;
                            case "LONG_PRESSED": Console.ForegroundColor = ConsoleColor.Yellow; break;
                            case "VLONG_PRESSED": Console.ForegroundColor = ConsoleColor.DarkYellow; break;
                            case "DOUBLE_PRESSED": Console.ForegroundColor = ConsoleColor.Green; break;
                        }
                        Console.WriteLine(EslInfo.ToString());
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine(EslInfo.ToString());
                    }
                }
            }

            if(Method == "GET")
            {
                return new EslServerApiObject("api/products", ESL, EslInfo.Message, Program.ApiKey, "POST", ProductId, "Description", $"{DateTime.Now:HH:mm:ss_dd-MM-yyyy}");
            }

            return new EslServerApiObject(ESL_ACTION.INPUT_RESPONSE.ToString(), ESL, EslInfo.Message, null, Event, EslInfo.Message.Equals("OK") ? "ACK" : "NAK", SequenceNumber, ButtonEventAction.NoAction.ToString(), EslLedColor.Magenta.ToString());
        }
    }
}
