using Microsoft.Extensions.Logging;
using PARR.EsppApi.Models;
using System.Text.Json;

namespace PARR.EsppApi
{
    internal class EsppHttpService
    {
        private readonly ILogger<EsppHttpService> logger;
        private readonly HttpClient httpClient;

        public EsppHttpService(ILogger<EsppHttpService> logger, HttpClient httpClient)
        {
            this.logger = logger;
            this.httpClient = httpClient;
        }

        public async Task<EsppResultBase<T>> SendAsync<T>(string query) where T : class
        {
            var request = new HttpRequestMessage(HttpMethod.Post, "");
            request.Content = new StringContent(query);

            try
            {
                logger.LogDebug($"Отправляю запрос в АСУ ЕСПП({query})");
                var response = await httpClient.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                    logger.LogError($"Ошибка при получении данных из АСУ ЕСПП, StatusCode:{response.StatusCode}");

                var responseString = await response.Content.ReadAsStringAsync();

                logger.LogDebug($"Получил данные, строка:  {responseString}");

                var errors = CheckErrors<T>(responseString, query);
                if (errors != null)
                    return errors;

                var obj = JsonSerializer.Deserialize<T>(responseString);


                return new EsppResultBase<T>(obj, true);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Ошибка при получении данных из АСУ ЕСПП");

                return new EsppResultBase<T>(null, false, ex);
            }
        }


        /// <summary>
        /// Проверка респонса на ошибки. В ЕСПП полный вест кост кастом
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private EsppResultBase<T>? CheckErrors<T>(string response, string query) where T : class
        {
            //Если вернет "ErrorCode":"0" - то все успешно прошло, если вернет другой ErrorCode, то не успешно
            //Не всегда возвращается ErrorCode, если получали например наряд, он вернет тело наряда
            if (response.Contains("ErrorCode") && response.Contains("Message"))
            {
                if (!response.Contains("\"ErrorCode\":\"0\""))
                {
                    logger.LogError(new Exception(response), $"Ошибка при выполнении запроса в ЕСПП. Тело запроса: {query}");

                    return new EsppResultBase<T>(null, false, new Exception($"Espp error: {response}"));
                }

                // ахахах! Может быть "ErrorCode":"0", и "Message":"Успешно", но в "MessageESPP":"err - Операция 'Прочее(работы)' не найденаЗапись \"Трудозатраты и Время в пути\" добавлена."
                // "Message":"Успешно","ErrorCode":"0","MessageESPP":"err - Операция 'Прочее(работы)' не найденаЗапись \"Трудозатраты и Время в пути\" добавлена."
                // т е это ошибка. рука лицо и привет разрабам ЕСПП
                // делаем тупо, может стоит переделать
                if (response.Contains("\"MessageESPP\":\"err"))
                {
                    logger.LogError(new Exception(response), $"Ошибка при выполнении запроса в ЕСПП. Тело запроса: {query}");

                    return new EsppResultBase<T>(null, false, new Exception($"Espp error: {response}"));
                }
            }

            return null;
        }

    }
}
