using Fitness_core_BE.Helpers; using Fitness_core_BE.Interfaces; using Fitness_core_BE.Interfaces.Services; using Fitness_core_BE.Models; using Fitness_core_BE.Infra.UoW; using System.Text.Json; namespace Fitness_core_BE.Services.ClientInvoice { public class ClientInvoiceService : IClientInvoiceService { private readonly IClientInvoiceRepository _clientInvoiceRepository; private readonly IUnitOfWork _uow; public ClientInvoiceService(IClientInvoiceRepository clientInvoiceRepository, IUnitOfWork uow) { _clientInvoiceRepository = clientInvoiceRepository; _uow = uow; } public async Task CreateClientInvoiceFromSubscription(object payload, HttpContext httpContext) { await _uow.BeginAsync(); try { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("subscriptionId")) { throw new KeyNotFoundException("subscriptionId is required"); } var subscriptionId = Guid.Parse(data["subscriptionId"].GetString()!); var result = await _clientInvoiceRepository.CreateClientInvoiceFromSubscription(subscriptionId); await _uow.CommitAsync(); return result; } catch { await _uow.RollbackAsync(); throw; } } public async Task GetClientInvoiceById(object payload, HttpContext httpContext) { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("clientInvoiceId")) { throw new KeyNotFoundException("clientInvoiceId is required"); } var clientInvoiceId = Guid.Parse(data["clientInvoiceId"].GetString()!); var clientInvoice = await _clientInvoiceRepository.GetClientInvoiceById(clientInvoiceId); if (clientInvoice == null) { throw new KeyNotFoundException("ClientInvoice not found"); } return clientInvoice; } public async Task GetClientInvoicesByClientId(object payload, HttpContext httpContext) { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("clientId")) { throw new KeyNotFoundException("clientId is required"); } var clientId = Guid.Parse(data["clientId"].GetString()!); return await _clientInvoiceRepository.GetClientInvoicesByClientId(clientId); } public async Task GetClientInvoicesByUserId(object payload, HttpContext httpContext) { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("userId")) { throw new KeyNotFoundException("userId is required"); } var userId = Guid.Parse(data["userId"].GetString()!); return await _clientInvoiceRepository.GetClientInvoicesByUserId(userId); } public async Task UpdateClientInvoiceStatus(object payload, HttpContext httpContext) { await _uow.BeginAsync(); try { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("clientInvoiceId") || !data.ContainsKey("status")) { throw new KeyNotFoundException("clientInvoiceId and status are required"); } var clientInvoiceId = Guid.Parse(data["clientInvoiceId"].GetString()!); var status = data["status"].GetString()!; // Validate status var validStatuses = new[] { "Pending", "Paid", "Failed", "Cancelled", "Refunded" }; if (!validStatuses.Contains(status)) { throw new InvalidOperationException($"Invalid status. Valid statuses are: {string.Join(", ", validStatuses)}"); } var result = await _clientInvoiceRepository.UpdateClientInvoiceStatus(clientInvoiceId, status); await _uow.CommitAsync(); return result; } catch { await _uow.RollbackAsync(); throw; } } public async Task CalculateClientInvoiceTotal(object payload, HttpContext httpContext) { var data = DeserializePayload.Deserialize(payload); if (!data!.ContainsKey("clientInvoiceId")) { throw new KeyNotFoundException("clientInvoiceId is required"); } var clientInvoiceId = Guid.Parse(data["clientInvoiceId"].GetString()!); var clientInvoice = await _clientInvoiceRepository.GetClientInvoiceById(clientInvoiceId); var total = clientInvoice?.Amount ?? 0; return new { Total = total }; } } }