using Domain.Dtos; using Domain.Dtos.Stock; using Domain.Entities; using Domain.Generics; using Microsoft.JSInterop; using System.Net.Http.Json; namespace phronCare.UIBlazor.Services.Stock.Expeditions { public class ExpeditionService: IExpeditionService { private readonly IJSRuntime _js; //Todavia no se utiliza pero eventualmente para exportaciones seguramente./ private readonly HttpClient _http; public ExpeditionService(HttpClient http, IJSRuntime js) { _js = js; _http = http; } /// /// Búsqueda de expediciones con filtros y paginación. /// Filtros típicos: número, estado, fechas, ubicación (opcional). /// /// Buscar expediciones (simétrico a QuoteService.SearchAsync) public async Task> SearchAsync( string? expeditionNumber = null, string? status = null, DateTime? issueDateFrom = null, DateTime? issueDateTo = null, int? locationId = null, int page = 1, int pageSize = 10) { var query = new List(); void Add(string key, string? val) { if (!string.IsNullOrWhiteSpace(val)) query.Add($"{key}={Uri.EscapeDataString(val)}"); } Add("expeditionNumber", expeditionNumber); Add("status", status); Add("issueDateFrom", issueDateFrom?.ToString("o")); Add("issueDateTo", issueDateTo?.ToString("o")); Add("locationId", locationId?.ToString()); Add("page", page.ToString()); Add("pageSize", pageSize.ToString()); // FIX: controller es singular => /api/expedition/search var url = "/api/expedition/search"; if (query.Any()) url += "?" + string.Join("&", query); var result = await _http.GetFromJsonAsync>(url); return result!; } /// /// Obtiene un presupuesto por QuoteNumber. /// public async Task GetQuoteByNumberAsync(string quoteNumber) { try { var result = await _http.GetFromJsonAsync($"api/quote/summary/{quoteNumber}"); return result; } catch (Exception ex) { Console.WriteLine($"Error al obtener QuoteDto por QuoteNumber: {ex.Message}"); return null; } } /// /// Envía el header + details de la expedición junto con el formSeriesId /// y recibe el número de expedición generado o un mensaje de error. /// public async Task CreateAndIssueAsync( ELSExpeditionHeader header, IEnumerable details, int formSeriesId) { // 1) Poner los ítems dentro del header header.PhLsmExpeditionDetails = details?.ToList() ?? new List(); var request = new CreateFullExpeditionRequest { Expedition = header, FormSeriesId = formSeriesId }; var response = await _http.PostAsJsonAsync("/api/expedition/createfull", request); if (!response.IsSuccessStatusCode) { var serverMessage = await response.Content.ReadAsStringAsync(); return new CreateExpeditionResult { Success = false, ErrorMessage = serverMessage }; } var result = await response.Content.ReadFromJsonAsync(); return result ?? new CreateExpeditionResult { Success = false, ErrorMessage = "Respuesta vacía del servidor." }; } /// /// Obtiene la expedición completa por ID para visualización (drawer/pantalla de detalle). /// public async Task GetDtoByIdAsync(int id) { try { var dto = await _http.GetFromJsonAsync($"/api/expedition/{id}"); return dto; } catch (Exception ex) { Console.WriteLine($"Error al obtener ExpeditionDto por ID: {ex.Message}"); return null; } } /// /// Descarga el PDF de la expedición en el navegador usando saveAsFile (base64). /// public async Task ExportPdfAsync(int expeditionId, string expeditionNumber) { try { var response = await _http.GetAsync($"/api/expedition/{expeditionId}/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 = $"{expeditionNumber}.pdf"; await _js.InvokeVoidAsync("saveAsFile", fileName, base64); } catch (Exception ex) { var message = ex.Message ?? "No message"; throw new Exception($"ExportPdfAsync: {message}", ex); } } } /// /// Contrato de request simétrico a CreateFullQuoteRequest. /// public class CreateFullExpeditionRequest { public ELSExpeditionHeader Expedition { get; set; } = default!; public int FormSeriesId { get; set; } } /// /// Resultado del create/issue simétrico a CreateQuoteResult. /// public class CreateExpeditionResult { public bool Success { get; set; } public int Id { get; set; } public string ExpeditionNumber { get; set; } = string.Empty; public string ErrorMessage { get; set; } = string.Empty; } // TODO: Ajustar namespace real si es distinto }