using AwInitilizer.Assist;
using AwInitilizer.Interface;
using AwInitilizer.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace AwInitilizer.Procedure
{
    public enum ProcedureStatus
    {
        Idle,Success,Failed
    }

    public class ProcedureBase
    {
        public string Name { get; set; }
        public string Content { get; set; }
        public bool IsActivated { get; set; } = true;

        public ProcedureStatus Status { get; private set; }
        public string InfoLog { get; internal set; }

        public static UpdateData UpdateData { get; set; }
        public static IIogger Logger { get; set; }

        public Dictionary<string, string> LogPair { get; private set; } = new Dictionary<string, string>();

        internal SerialPortocol serialPortocol { get; private set; }

        internal static string ServerIpAddress = "192.168.1.10";

        public async Task<bool> DoWork() {
            if (!IsActivated)
                return false;
            InfoLog = "";
            Logger.Print(Name + "Started");
            var result = await Run();
            Dispose();
            Status = result ? ProcedureStatus.Success : ProcedureStatus.Failed;
            Logger.Print(Name + "Complete");
            return result;
        }

        internal virtual async Task<bool> Run()
        {
            return true;
        }

        public void Reset()
        {
            Status = ProcedureStatus.Idle;
            InfoLog = "";
        }

        internal async Task<bool> CheckAndCreateSocket()
        {
            TcpSerializer socketConnection = null;
            if (socketConnection == null || socketConnection.ConnectStatus == ConnectStatus.ConnectionFail ||
                socketConnection.ConnectStatus == ConnectStatus.DisConnected)
            {
                socketConnection = new Assist.TcpSerializer(ip:ServerIpAddress);
                await socketConnection.OpenAsync();
                if(socketConnection.ConnectStatus != ConnectStatus.Connected)
                {
                    Logger.Print("EVSE tcp connection Failed,Check EVSE is connected", isError: true);
                    return false;
                }
                Logger.Print("Connected");

                serialPortocol = new SerialPortocol(socketConnection);
                return true;
            }
            return true;
        }

        internal async Task<bool> ChekCsuBootCompelete()
        {
            //await Task.Delay(TimeSpan.FromMinutes(2));
            try
            {
                using (WebClientTimeout webClient = new WebClientTimeout())
                {
                    NameValueCollection parameters = new NameValueCollection();
                    parameters.Add("opt", "2");
                    webClient.QueryString = parameters;

                    using (Stream stream = await webClient.OpenReadTaskAsync($"https://{ServerIpAddress}/get_query_action.php"))
                    // 使用 StreamReader 讀取 stream 內的字元
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        // 將 StreamReader 所讀到的字元轉為 string
                        string request = reader.ReadToEnd();
                        Regex rx = new Regex("(SystemStatus)\\\": ([0-9]*)");
                        var matches = rx.Matches(request);
                        bool isAllPassed = true;
                        for (int matchIndex = 0; matchIndex < matches.Count; matchIndex++)
                        {
                            var match = matches[matchIndex];
                            if (match.Groups.Count != 3)
                            {
                                isAllPassed = false;
                                break;
                            }
                            else
                            {
                                if (match.Groups[2].Value != "1")
                                {
                                    isAllPassed = false;
                                    break;
                                }
                            }
                        }

                        return isAllPassed;
                    }
                }
            }
            catch (Exception e)
            {
                return false;
            }
        }

        private void Dispose()
        {
            if(serialPortocol!=null)
            {
                try
                {
                    serialPortocol.Close();
                }catch
                { 
                }
            }
        }
    }
}