using Fitness_core_BE.DTOs.PlatformBilling; using Fitness_core_BE.Helpers; using Fitness_core_BE.Interfaces.Services; using Fitness_core_BE.Models.IOs; using Microsoft.AspNetCore.Mvc; using static Fitness_core_BE.Helpers.JwtMiddleware; using static Fitness_core_BE.Helpers.ApiResponseHelper; namespace Fitness_core_BE.Controllers { // Platform billing (HexaFitness -> gym): pricing configuration and invoicing. // The gym-owner side of this same concern lives in ClientInvoiceController. [ApiController] [Route("api/admin")] [CustomMiddleware] [TenantResolution] public class AdminBillingController : ControllerBase { private readonly IPlatformBillingService _platformBilling; public AdminBillingController(IPlatformBillingService platformBilling) { _platformBilling = platformBilling; } [HttpGet("pricing-plans")] public async Task>>> ListPricingPlans() { return Response(await _platformBilling.GetPricingPlansAsync(HttpContext.RequestAborted)); } [HttpPut("pricing-plans")] public async Task>> UpsertPricingPlan([FromBody] UpsertPricingPlanRequest request) { return Response(await _platformBilling.UpsertPricingPlanAsync(request, HttpContext.RequestAborted)); } [HttpGet("device-pricing")] public async Task>> GetDevicePricing() { return Response(await _platformBilling.GetDevicePricingAsync(HttpContext.RequestAborted)); } [HttpPut("device-pricing")] public async Task>> UpdateDevicePricing([FromBody] DevicePricingDto request) { return Response(await _platformBilling.UpdateDevicePricingAsync(request, HttpContext.RequestAborted)); } [HttpPost("clients/{id:guid}/pricing-plan")] public async Task>> AssignPricingPlan(Guid id, [FromBody] AssignPricingPlanRequest request) { var invoice = await _platformBilling.AssignPricingPlanAsync(id, request, HttpContext.RequestAborted); return Response(new { assigned = true, clientInvoiceId = invoice.ClientInvoiceId, amount = invoice.Amount }); } [HttpGet("clients/{id:guid}/platform-fee")] public async Task>> GetPlatformFee(Guid id) { return Response(await _platformBilling.ComputeMonthlyFeeAsync(id, HttpContext.RequestAborted)); } [HttpGet("invoices/pending")] public async Task>>> ListPendingInvoices() { return Response(await _platformBilling.GetPendingInvoicesAsync(HttpContext.RequestAborted)); } [HttpGet("invoices/completed")] public async Task>>> ListCompletedInvoices() { return Response(await _platformBilling.GetCompletedInvoicesAsync(HttpContext.RequestAborted)); } [HttpPost("invoices/{id:guid}/payments")] public async Task>> RecordInvoicePayment(Guid id, [FromBody] RecordClientInvoicePaymentRequest request) { return Response(await _platformBilling.RecordClientInvoicePaymentAsync(id, request.Amount, HttpContext.RequestAborted)); } [HttpPost("invoices/{id:guid}/send-payment-link")] public async Task>> SendInvoicePaymentLink(Guid id) { return Response(await _platformBilling.SendClientPaymentLinkAsync(id, HttpContext.RequestAborted)); } [HttpPost("billing/run-monthly")] public async Task>> RunMonthlyBilling() { var invoices = await _platformBilling.RunMonthlyBillingForAllClientsAsync(HttpContext.RequestAborted); return Response(new { generated = invoices.Count }); } } }