using DevExpress.Data.Filtering;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Persistent.Base;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Nuvolar.Module.StaticClass
{
    /// <summary>
    /// Laravel RestAPI kezelő osztály
    /// </summary>
    public static class RestAPI
    {
        private static string _UriBase;
        private static Dictionary<string, string> _LoginInfo;
        private static int _StatusCode;
        private static string _StatusMessage;
        private static string _ResponseMessage;
        private static string _API_Token;
        private static string _GeocodeAPIKey;

        public static int StatusCode
        {
            get { return _StatusCode; }
        }
        public static string StatusMessage
        {
            get { return _StatusMessage; }
        }
        public static string ResponseMessage
        {
            get { return _ResponseMessage; }
        }
        public static void Init(XPObjectSpace _onew)
        {

            _ResponseMessage = "";
            _UriBase = ConfigurationManager.AppSettings["Uri"];
            _GeocodeAPIKey = ConfigurationManager.AppSettings["GeocodeAPIKey"];
            Laravel.Users _Users = _onew.FindObject<Laravel.Users>(CriteriaOperator.Parse("email='sysadmin@emango.com'"));
            if (_Users != null)
            {
                if (String.IsNullOrEmpty(_Users.api_token))
                {

                    _LoginInfo = new Dictionary<string, string> { { "email", "sysadmin@emango.com" },
                                                          { "password", "SysAdmin" }};

                    var json = ExecuteRootePOST("login", false, JsonConvert.SerializeObject(_LoginInfo));

                    if (_StatusCode == 200)
                    {
                        var dd = JsonConvert.DeserializeObject(json);
                        var dict = JObject.Parse(json).SelectToken("data").ToObject<Dictionary<string, string>>();
                        _API_Token = dict["api_token"];

                        Tracing.Tracer.LogText(string.Format("API Token requested : {0}", _API_Token.ToString()));
                    }
                    else
                    {
                        Tracing.Tracer.LogText("API Token request fail!");
                    }
                }
                else
                {
                    _API_Token = _Users.api_token;
                    Tracing.Tracer.LogText(string.Format("API Token found : {0}", _API_Token.ToString()));
                }
            }
            else
            {
                Tracing.Tracer.LogText("Laravel user not found!");
            }
        }
        public static string ExecuteRootePOST(string _RooteString, bool _NeedAuthentication, string _postData)
        {
            _StatusCode = 500;
            _StatusMessage = "Not respond ...";
            string json = "";


            Tracing.Tracer.LogText(_UriBase + _RooteString);
            Tracing.Tracer.LogText(_postData);

            try
            {
                var _Uri = new Uri(_UriBase + _RooteString, UriKind.Absolute);
                var _WebRequest = WebRequest.Create(_Uri);
                HttpWebRequest _HttpWebRequest = (HttpWebRequest)_WebRequest;

                _HttpWebRequest.Method = "POST";
                byte[] byteArray = Encoding.UTF8.GetBytes(_postData);


                if (_NeedAuthentication)
                {
                    _HttpWebRequest.PreAuthenticate = true;
                    _HttpWebRequest.Headers.Add("Authorization", "Bearer " + _API_Token);
                    _HttpWebRequest.Headers.Add("cdb", GeneralFunction.GLOBAL_SQLDatabase);
                }

                _HttpWebRequest.ContentType = "application/json";
                _HttpWebRequest.Accept = "application/json";
                _HttpWebRequest.ContentLength = byteArray.Length;
                Stream _dataStream = _HttpWebRequest.GetRequestStream();
                _dataStream.Write(byteArray, 0, byteArray.Length);
                _dataStream.Close();

                Tracing.Tracer.LogText("Web request initialized !");

                try
                {
                    WebResponse _WebResponse = _WebRequest.GetResponse();
                    _StatusCode = (int)((HttpWebResponse)_WebResponse).StatusCode;
                    _StatusMessage = ((HttpWebResponse)_WebResponse).StatusDescription;
                    var _responseStream = _WebResponse.GetResponseStream();
                    if (_responseStream != null)
                    {
                        var _StreamReader = new StreamReader(_responseStream, Encoding.Default);
                        json = _StreamReader.ReadToEnd();
                    }
                    else
                    {
                        return json;
                    }
                    try
                    {
                        _StatusMessage = JsonConvert.DeserializeObject(json).ToString();
                    }
                    catch (Exception ex)
                    {
                        Tracing.Tracer.LogText(ex.Message);
                    }


                    _responseStream.Close();
                    _WebResponse.Close();
                }
                catch (WebException ex)
                {
                    Tracing.Tracer.LogText(ex.Message);

                    if (ex.Status == WebExceptionStatus.ProtocolError)
                    {
                        var _WebResponse = (HttpWebResponse)ex.Response;
                        _StatusCode = (int)_WebResponse.StatusCode;
                        _StatusMessage = ((HttpWebResponse)_WebResponse).StatusDescription;
                    }
                }
            }
            catch (Exception ex)
            {
                Tracing.Tracer.LogText(ex.Message);
            }
            return json;
        }
        public static string ExecuteRooteGET(string _RooteString, bool _NeedAuthentication)
        {
            string json = "";

            Tracing.Tracer.LogText(_UriBase + _RooteString);

            var _Uri = new Uri(_UriBase + _RooteString, UriKind.Absolute);
            var _WebRequest = WebRequest.Create(_Uri);
            _WebRequest.Method = "GET";


            HttpWebRequest _HttpWebRequest = (HttpWebRequest)_WebRequest;
            if (_NeedAuthentication)
            {
                _HttpWebRequest.PreAuthenticate = true;
                _HttpWebRequest.Headers.Add("Authorization", "Bearer " + _API_Token);
                _HttpWebRequest.Headers.Add("cdb", GeneralFunction.GLOBAL_SQLDatabase);
            }

            _HttpWebRequest.Accept = "application/json";
            _HttpWebRequest.ContentType = "application/json";

            try
            {
                WebResponse _WebResponse = _WebRequest.GetResponse();
                _StatusCode = (int)((HttpWebResponse)_WebResponse).StatusCode;
                Stream _responseStream = _WebResponse.GetResponseStream();
                if (_responseStream == null) return json;

                StreamReader _StreamReader = new StreamReader(_responseStream, Encoding.Default);
                json = _StreamReader.ReadToEnd();

                _responseStream.Close();
                _WebResponse.Close();
            }
            catch (WebException ex)
            {

                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    var _WebResponse = (HttpWebResponse)ex.Response;
                    _StatusCode = (int)_WebResponse.StatusCode;
                }
            }


            return json;
        }
        public static string ExecuteGOOGLEMAPSGET(string _RouteString)
        {
            string json = "";

            Tracing.Tracer.LogText(_UriBase + _RouteString);


            var _Uri = new Uri("https://maps.googleapis.com/maps/api/geocode/json?address=" + _RouteString + "&key=" + _GeocodeAPIKey, UriKind.Absolute);
            var _WebRequest = WebRequest.Create(_Uri);
            _WebRequest.Method = "GET";


            HttpWebRequest _HttpWebRequest = (HttpWebRequest)_WebRequest;

            _HttpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
            _HttpWebRequest.ContentType = "application/json";
            _HttpWebRequest.Headers.Add("accept-language", "hu-HU,hu;q=0.9,en-US;q=0.8,en;q=0.7,pt;q=0.6");

            try
            {
                WebResponse _WebResponse = _WebRequest.GetResponse();
                _StatusCode = (int)((HttpWebResponse)_WebResponse).StatusCode;
                Stream _responseStream = _WebResponse.GetResponseStream();
                if (_responseStream == null) return json;

                StreamReader _StreamReader = new StreamReader(_responseStream, Encoding.Default);
                json = _StreamReader.ReadToEnd();

                _responseStream.Close();
                _WebResponse.Close();
            }
            catch (WebException ex)
            {

                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    var _WebResponse = (HttpWebResponse)ex.Response;
                    _StatusCode = (int)_WebResponse.StatusCode;
                }
            }


            return json;
        }
    }
}
