using Domain.Dtos;
using Domain.Entities;
using Domain.Generics;
using Microsoft.JSInterop;
using System.Net.Http.Json;
using System.Reflection;
using System.Text;
using System.Text.Json;

namespace phronCare.UIBlazor.Services.Sales.Quotes
{
    public class QuoteService:IQuoteService
    {
        private readonly IJSRuntime _js;
        private readonly HttpClient _http;
        public QuoteService(HttpClient http, IJSRuntime js)
        {
            _js = js;
            _http = http;
        }

        /// <summary>
        /// Envía el EQuoteHeader junto con el formSeriesId al backend
        /// y recibe el número de presupuesto generado o un error.
        /// </summary>
        public async Task<CreateQuoteResult> CreateFullQuoteAsync(EQuoteHeader quote, int formSeriesId)
        {
            var request = new CreateFullQuoteRequest
            {
                Quote = quote,
                FormSeriesId = formSeriesId
            };

            var response = await _http.PostAsJsonAsync("/api/quote/createfull", request);

            if (!response.IsSuccessStatusCode)
            {
                var serverMessage = await response.Content.ReadAsStringAsync();
                return new CreateQuoteResult
                {
                    Success = false,
                    ErrorMessage = serverMessage
                };
            }

            var result = await response.Content.ReadFromJsonAsync<CreateQuoteResult>();
            return result!;
        }

        /// <summary>
        /// Busca presupuestos con filtros y paginación.
        /// </summary>
        public async Task<PagedResult<QuoteDto>> SearchAsync(
            int? customerId = null,
            string? customerText = null,
            string? quoteNumber = null,
            int? professionalId = null,
            string? professionalText = null,
            int? institutionId = null,
            string? institutionText = null,
            int? patientId = null,
            string? patientText = null,
            string? status = null,
            DateTime? issueDateFrom = null,
            DateTime? issueDateTo = null,
            int page = 1,
            int pageSize = 10)
        {
            // Construir manualmente la query string
            var queryParams = new List<string>();

            void AddParam(string key, string? value)
            {
                if (!string.IsNullOrWhiteSpace(value))
                    queryParams.Add($"{key}={Uri.EscapeDataString(value!)}");
            }

            AddParam("customerId", customerId?.ToString());
            AddParam("customerText", customerText);
            AddParam("quoteNumber", quoteNumber);
            AddParam("professionalId", professionalId?.ToString());
            AddParam("professionalText", professionalText);
            AddParam("institutionId", institutionId?.ToString());
            AddParam("institutionText", institutionText);
            AddParam("patientId", patientId?.ToString());
            AddParam("patientText", patientText);
            AddParam("status", status);
            AddParam("issueDateFrom", issueDateFrom?.ToString("o"));
            AddParam("issueDateTo", issueDateTo?.ToString("o"));
            AddParam("page", page.ToString());
            AddParam("pageSize", pageSize.ToString());

            var url = "/api/quote/search";
            if (queryParams.Any())
                url += "?" + string.Join("&", queryParams);

            // Llamada al endpoint
            var result = await _http.GetFromJsonAsync<PagedResult<QuoteDto>>(url);
            return result!;
        }
        /// <summary>
        /// Obtiene el PDF del presupuesto por ID como array de bytes.
        /// </summary>
        public async Task ExportPdfAsync(int quoteId, string quoteNumber)
        {
            try
            {
                var response = await _http.GetAsync($"/api/quote/{quoteId}/pdf");

                if (!response.IsSuccessStatusCode)
                {
                    var error = await response.Content.ReadAsStringAsync();
                    throw new Exception($"Error al generar PDF: {error}");
                }

                var bytes = await response.Content.ReadAsByteArrayAsync();
                var base64 = Convert.ToBase64String(bytes);
                var fileName = $"{quoteNumber}.pdf";

                await _js.InvokeVoidAsync("saveAsFile", fileName, base64);


            }
            catch (Exception ex)
            {
                var message = ex.Message ?? "No message";
                throw new Exception($"ExportPdfAsync: {message}", ex);
            }
        }
        /// <summary>
        /// Envía una solicitud al backend para autorizar un presupuesto específico.
        /// </summary>
        public async Task<bool> AuthorizeQuoteAsync(QuoteAuthorizationRequest request)
        {
            var response = await _http.PostAsJsonAsync("/api/quote/authorize", request);

            if (!response.IsSuccessStatusCode)
            {
                var serverMessage = await response.Content.ReadAsStringAsync();
                throw new Exception($"Error al autorizar el presupuesto: {serverMessage}");
            }

            return true;
        }

        /// <summary>
        /// Obtiene un presupuesto completo por ID para su visualización y autorización.
        /// </summary>
        public async Task<QuoteDto?> GetDtoByIdAsync(int id)
        {
            try
            {
                var result = await _http.GetFromJsonAsync<QuoteDto>($"/api/quote/{id}");
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error al obtener QuoteDto por ID: {ex.Message}");
                return null;
            }
        }
        public async Task ExportFilteredAsync(QuoteSearchParams searchParams)
        {
            try
            {
                var content = new StringContent(JsonSerializer.Serialize(searchParams), Encoding.UTF8, "application/json");
                var response = await _http.PostAsync("api/quote/exportfiltered", content);

                //response.EnsureSuccessStatusCode();
                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new Exception(errorContent);
                }
                var bytes = await response.Content.ReadAsByteArrayAsync();
                var base64 = Convert.ToBase64String(bytes);
                var timestamp = DateTime.Now.ToString("yyyyMMddHHmm");
                var fileName = $"{timestamp}_quotes.xlsx";
                await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
            }
            catch (Exception ex)
            {
                var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
                var message = ex.Message ?? "No message provided";
                throw new Exception($"{message}", ex);
            }
        }

    }

    public class CreateQuoteResult
    {
        public bool Success { get; set; }
        public int Id { get; set; }
        public string QuoteNumber { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
    }

    public class CreateFullQuoteRequest
    {
        public EQuoteHeader Quote { get; set; } = default!;
        public int FormSeriesId { get; set; }
    }
}
