using LibraryManagement.Shared.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace Backend.Features.Subscriptions { [ApiController] [Route("api")] public class SubscriptionController : ControllerBase { private readonly ISubscriptionService _subscriptionService; public SubscriptionController(ISubscriptionService subscriptionService) { _subscriptionService = subscriptionService; } [HttpGet("memberships")] [AllowAnonymous] public async Task>> GetMemberships() { return Ok(await _subscriptionService.GetMembershipsAsync()); } [HttpGet("subscriptions/me")] [Authorize] public async Task> GetMySubscription() { var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(userIdStr)) return Unauthorized(); var userId = Guid.Parse(userIdStr); var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId); if (subscription == null) return NotFound(new { message = "No active subscription found." }); return Ok(subscription); } [HttpGet("subscriptions/me/all")] [Authorize] public async Task>> GetMyAllSubscriptions() { var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(userIdStr)) return Unauthorized(); var userId = Guid.Parse(userIdStr); var subscriptions = await _subscriptionService.GetUserAllSubscriptionsAsync(userId); return Ok(subscriptions); } [HttpPost("subscriptions/subscribe")] [Authorize] public async Task> Subscribe([FromBody] SubscribeRequest request) { try { var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(userIdStr)) return Unauthorized(); var userId = Guid.Parse(userIdStr); // For cash payments, we create a pending subscription var subscription = await _subscriptionService.CreatePendingSubscriptionAsync(userId, request.MembershipId); return Ok(subscription); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpGet("subscriptions/user/{userId}")] [Authorize(Roles = "Librarian")] public async Task> GetUserSubscription(Guid userId) { var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId); if (subscription == null) return NotFound(new { message = "No active subscription found." }); return Ok(subscription); } [HttpGet("subscriptions/all")] [Authorize(Roles = "Librarian")] public async Task>> GetSubscriptions() { return Ok(await _subscriptionService.GetAllSubscriptionsAsync()); } [HttpPost("subscriptions/admin-subscribe")] [Authorize(Roles = "Librarian")] public async Task> AdminSubscribe([FromBody] AdminSubscribeRequest request) { try { var subscription = await _subscriptionService.SubscribeUserAsync(request.UserId, request.MembershipId); return Ok(subscription); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpGet("subscriptions/preview-upgrade/{membershipId}")] [Authorize] public async Task> GetUpgradePreview(int membershipId) { var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(userIdStr)) return Unauthorized(); var preview = await _subscriptionService.GetUpgradePreviewAsync(Guid.Parse(userIdStr), membershipId); return Ok(preview); } [HttpPost("subscriptions/subscribe-wallet")] [Authorize] public async Task> SubscribeWithWallet([FromBody] SubscribeRequest request) { try { var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(userIdStr)) return Unauthorized(); var subscription = await _subscriptionService.SubscribeWithWalletAsync(Guid.Parse(userIdStr), request.MembershipId); return Ok(subscription); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpGet("subscriptions/pending")] [Authorize(Roles = "Librarian")] public async Task>> GetPendingSubscriptions() { return Ok(await _subscriptionService.GetPendingSubscriptionsAsync()); } [HttpPost("subscriptions/approve")] [Authorize(Roles = "Librarian")] public async Task ApproveSubscription([FromBody] ApproveSubscriptionRequest request) { var success = await _subscriptionService.ApproveSubscriptionAsync(request.SubscriptionId, request.Approve); if (!success) return NotFound(new { message = "Subscription not found." }); return Ok(new { message = request.Approve ? "Subscription approved." : "Subscription rejected." }); } } }