using System;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using RestSharp;

namespace HorseRacingPredictor.Manager
{
    internal class API
    {
        // Intervallo tra le chiamate API per evitare limitazioni di rate
        private const int DefaultApiCallDelay = 6000;

        /// <summary>
        /// Esegue una chiamata API generica e restituisce la risposta
        /// </summary>
        public static RestResponse ExecuteApiRequest(string url, string apiKey, string apiKeyHeader, string hostHeader, string hostValue, int delay = DefaultApiCallDelay)
        {
            var clientApi = new RestClient(url);
            var request = new RestRequest();
            request.AddHeader(apiKeyHeader, apiKey);
            request.AddHeader(hostHeader, hostValue);

            try
            {
                var response = clientApi.Execute(request);
                if (!response.IsSuccessful)
                {
                    throw new Exception($"Errore nella richiesta API: {response.ErrorMessage}");
                }

                // Aggiungi una pausa tra una chiamata e l'altra
                if (delay > 0)
                {
                    Thread.Sleep(delay);
                }

                return response;
            }
            catch (Exception ex)
            {
                throw new Exception($"Errore durante la richiesta API: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// Esegue una chiamata API generica con informazioni di tipo per il salvataggio nel database
        /// </summary>
        public static RestResponse ExecuteApiRequest(string url, string apiKey, string apiKeyHeader, string hostHeader, string hostValue, 
                                                    string apiType, string parameters, int delay = DefaultApiCallDelay)
        {
            // La logica è la stessa ma ora passa anche i parametri necessari per salvare nel database
            return ExecuteApiRequest(url, apiKey, apiKeyHeader, hostHeader, hostValue, delay);
        }

        /// <summary>
        /// Versione asincrona di ExecuteApiRequest
        /// </summary>
        public static async Task<RestResponse> ExecuteApiRequestAsync(string url, string apiKey, string apiKeyHeader, string hostHeader, string hostValue, int delay = DefaultApiCallDelay)
        {
            var clientApi = new RestClient(url);
            var request = new RestRequest();
            request.AddHeader(apiKeyHeader, apiKey);
            request.AddHeader(hostHeader, hostValue);

            try
            {
                var response = await clientApi.ExecuteAsync(request);
                if (!response.IsSuccessful)
                {
                    throw new Exception($"Errore nella richiesta API: {response.ErrorMessage}");
                }

                // Aggiungi una pausa tra una chiamata e l'altra
                if (delay > 0)
                {
                    await Task.Delay(delay);
                }

                return response;
            }
            catch (Exception ex)
            {
                throw new Exception($"Errore durante la richiesta API: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// Versione asincrona di ExecuteApiRequest con informazioni di tipo
        /// </summary>
        public static async Task<RestResponse> ExecuteApiRequestAsync(string url, string apiKey, string apiKeyHeader, string hostHeader, string hostValue, 
                                                                      string apiType, string parameters, int delay = DefaultApiCallDelay)
        {
            // La logica è la stessa ma ora passa anche i parametri necessari per salvare nel database
            return await ExecuteApiRequestAsync(url, apiKey, apiKeyHeader, hostHeader, hostValue, delay);
        }

        /// <summary>
        /// Salva la risposta dell'API su file per debugging
        /// </summary>
        public static void SaveResponseToFile(string url, string content, string baseFolderName = "ApiResponses")
        {
            try
            {
                string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, baseFolderName);
                
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                string fileName = Path.Combine(folderPath, $"ApiResponse_{DateTime.Now:yyyyMMdd_HHmmss}.json");
                
                File.WriteAllText(fileName, content);
            }
            catch (Exception ex)
            {
                throw new Exception($"Errore durante il salvataggio della risposta API: {ex.Message}", ex);
            }
        }
    }
}
