using Domain.Dtos.Stock;
using Domain.Entities;
using Domain.Generics;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System.Net.Http.Json;
using System.Reflection;
using System.Text;
using System.Text.Json;

namespace phronCare.UIBlazor.Services.Stock
{
    public class LSProductService
    {
        private readonly HttpClient _http;
        private readonly IJSRuntime _js;

        public LSProductService(HttpClient http, IJSRuntime js)
        {
            _http = http;
            _js = js;
        }

        public async Task<PagedResult<ELSProduct>?> SearchAsync(LSProductSearchParams searchParams)
        {
            return await _http.PostAsJsonAsync("/api/LSProduct/Search", searchParams)
                              .ContinueWith(async t =>
                                  await t.Result.Content.ReadFromJsonAsync<PagedResult<ELSProduct>>())
                              .Unwrap();
        }

        public async Task<ELSProduct?> GetByIdAsync(int id)
        {
            return await _http.GetFromJsonAsync<ELSProduct>($"/api/LSProduct/{id}");
        }

        public async Task<HttpResponseMessage> CreateAsync(ELSProduct product)
        {
            return await _http.PostAsJsonAsync("/api/LSProduct/create", product);
        }

        public async Task<HttpResponseMessage> UpdateAsync(ELSProduct product)
        {
            return await _http.PutAsJsonAsync("/api/LSProduct/update", product);
        }

        public async Task<HttpResponseMessage> DeleteAsync(int id)
        {
            return await _http.DeleteAsync($"/api/LSProduct/{id}");
        }

        public async Task ExportFilteredAsync(LSProductSearchParams searchParams)
        {
            try
            {
                var content = new StringContent(JsonSerializer.Serialize(searchParams), Encoding.UTF8, "application/json");
                var response = await _http.PostAsync("/api/LSProduct/exportfiltered", content);

                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 = $"productos_{DateTime.Now:yyyyMMddHHmmss}.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 async Task DownloadTemplateAsync()
        {
            var response = await _http.GetAsync("/api/LSProduct/download-template");

            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                throw new Exception($"No se pudo descargar la plantilla: {errorContent}");
            }

            var bytes = await response.Content.ReadAsByteArrayAsync();
            var base64 = Convert.ToBase64String(bytes);
            await _js.InvokeVoidAsync("saveAsFile", "plantilla_productos.xlsx", base64);
        }
        public async Task<List<ProductImportPreviewDto>> PreviewImportAsync(IBrowserFile file)
        {
            using var content = new MultipartFormDataContent();
            var stream = file.OpenReadStream(maxAllowedSize: 10 * 1024 * 1024); // 10MB
            content.Add(new StreamContent(stream), "file", file.Name);

            var response = await _http.PostAsync("api/LSProduct/preview-import", content);
            response.EnsureSuccessStatusCode();

            var result = await response.Content.ReadFromJsonAsync<List<ProductImportPreviewDto>>();
            return result ?? new();
        }

        public async Task<ProductImportResultDto?> ConfirmImportAsync(IEnumerable<ProductImportPreviewDto> items)
        {
            // solo envía los registros válidos
            var valid = items.Where(x => !x.HasError).ToList();

            var response = await _http.PostAsJsonAsync("api/LSProduct/import", valid);

            response.EnsureSuccessStatusCode();
            return await response.Content.ReadFromJsonAsync<ProductImportResultDto>();
        }
    }
}
