using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Edge.WebHost.Models;
using Edge.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RestSharp;

namespace Edge.WebHost.Controllers
{
    public class WebConsoleHomeController : Controller
    {
        private readonly ILogger<WebConsoleHomeController> _logger;
        JsonSerializerSettings _jsonSetting =
            new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
        private readonly IApiDescriptionGroupCollectionProvider _apiDescriptionsProvider;
        private string _apiBaseAddress;
        private string _checkLicenseUrl;
        private string _verifyLicenseUrl;
        private readonly string _serviceDiscoveryUrl;

        public WebConsoleHomeController(ILogger<WebConsoleHomeController> logger,
            IApiDescriptionGroupCollectionProvider apiDescriptionsProvider,
            IConfiguration configuration)
        {
            
            _logger = logger;
            _apiDescriptionsProvider = apiDescriptionsProvider;
            _apiBaseAddress = configuration.GetValue<string>("BaseUrl");
            _checkLicenseUrl = configuration.GetValue<string>("CheckLicenseUrl");
            _verifyLicenseUrl = configuration.GetValue<string>("VerifyLicenseUrl");
            _serviceDiscoveryUrl = configuration.GetValue<string>("ServiceDiscoveryUrl");
        }

        public async Task<IActionResult> Index()
        {
            var applicableApiDescriptions = _apiDescriptionsProvider.ApiDescriptionGroups.Items
                   .SelectMany(group => group.Items);
            if (HttpContext != null)
            {
                _apiBaseAddress = "http://"+HttpContext.Request.Host.Value+"/";
            }
            if (await CheckLicense() == true)
            {
                return View("../WebConsole/Home/Index", _apiDescriptionsProvider.ApiDescriptionGroups.Items
                   .SelectMany(group => group.Items));
            }
            else
            {
               return View("../WebConsole/Home/InputLicense", Licensing.Instance().GetMacAddress(_logger));
            }
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModelWeb { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

        public async Task<IActionResult> InputLicense()
        {
            return View("InputLicense");
        }

        public async Task<IActionResult> SaveLicense(string license)
        {
            if (await LicenseVerify(license) == true)
            {
                return RedirectToAction(nameof(Index), _apiDescriptionsProvider.ApiDescriptionGroups.Items.SelectMany(group => group.Items));
            }
            else
            {
                return View("InputLicense");
            }
        }

        private async Task<bool> CheckLicense()
        {
            var result = false;
            var path = await getServiceUrl("webapi", "CheckLicense", "LicensingApp");
           
            if (path != string.Empty)
            {
                _checkLicenseUrl = path;
            }
            try
            {
                var restClient = new RestClient(_apiBaseAddress);
                RestRequest request = new RestRequest(_checkLicenseUrl, Method.POST);
                request.AddHeader("Content-Type", "application/json");
                request.AddJsonBody("");
                request.RequestFormat = DataFormat.Json;

                var response = await restClient.ExecuteTaskAsync(request);

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    _logger.LogInformation($"CheckLicense {_checkLicenseUrl} with Status code: " + response.StatusCode);
                }
                else
                {
                    result = JsonConvert.DeserializeObject<bool>(response.Content);
                }
            }
            catch (Exception _)
            {

            }
            return result;
        }

        private async Task<bool> LicenseVerify(string license)
        {
            var result = false;
            try
            {
                var path = await getServiceUrl("webapi", "VerifyLicense", "LicensingApp");
                if (path != string.Empty)
                {
                    _verifyLicenseUrl = path;
                }
                var restClient = new RestClient(_apiBaseAddress);
                RestRequest request = new RestRequest(_verifyLicenseUrl, Method.POST);
                request.AddHeader("Content-Type", "application/json");
                request.AddJsonBody(license);
                request.RequestFormat = DataFormat.Json;

                var response = await restClient.ExecuteTaskAsync(request);

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    _logger.LogInformation($"LicenseVerify {_verifyLicenseUrl} with Status code: " + response.StatusCode);
                }
                else
                {
                    result = JsonConvert.DeserializeObject<bool>(response.Content);
                }
            }
             
            catch (Exception _)
            {
                
            }
            return result;
        }
        /// <summary>
        /// serviceType canbe "webapi"/"localMqtt"/"remotemqtt"
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="apiName"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        private async Task<string> getServiceUrl(string serviceType,string apiName,string tag)
        {
            var result = string.Empty;
            object[] requestBody = new object[]{ serviceType, new object[] { tag} };

            try
            {
                var restClient = new RestClient(_apiBaseAddress);
                RestRequest request = new RestRequest(_serviceDiscoveryUrl, Method.POST);
                request.AddHeader("Content-Type", "application/json");
                request.AddJsonBody(requestBody);
                request.RequestFormat = DataFormat.Json;

                var response = await restClient.ExecuteTaskAsync(request);

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    _logger.LogInformation($"serviceDiscovery {_serviceDiscoveryUrl} with Status code: " + response.StatusCode);
                }
                else
                {
                    var data = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(response.Content);
                    if (data.Count > 0)
                    {
                        foreach (var d in data)
                        {
                            if (d["ApiName"].ToString() == apiName)
                            {
                                result = d["Path"].ToString().Substring(1);
                                break;
                            }
                        }
                    }
                }
            }

            catch (Exception _)
            {

            }
            return result;
        }
    }
}