package handlers import ( "net/http" "github.com/labstack/echo/v4" "github.com/treytartt/casera-api/internal/apperrors" "github.com/treytartt/casera-api/internal/middleware" "github.com/treytartt/casera-api/internal/models" "github.com/treytartt/casera-api/internal/services" ) // SubscriptionHandler handles subscription-related HTTP requests type SubscriptionHandler struct { subscriptionService *services.SubscriptionService } // NewSubscriptionHandler creates a new subscription handler func NewSubscriptionHandler(subscriptionService *services.SubscriptionService) *SubscriptionHandler { return &SubscriptionHandler{subscriptionService: subscriptionService} } // GetSubscription handles GET /api/subscription/ func (h *SubscriptionHandler) GetSubscription(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) subscription, err := h.subscriptionService.GetSubscription(user.ID) if err != nil { return err } return c.JSON(http.StatusOK, subscription) } // GetSubscriptionStatus handles GET /api/subscription/status/ func (h *SubscriptionHandler) GetSubscriptionStatus(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) status, err := h.subscriptionService.GetSubscriptionStatus(user.ID) if err != nil { return err } return c.JSON(http.StatusOK, status) } // GetUpgradeTrigger handles GET /api/subscription/upgrade-trigger/:key/ func (h *SubscriptionHandler) GetUpgradeTrigger(c echo.Context) error { key := c.Param("key") trigger, err := h.subscriptionService.GetUpgradeTrigger(key) if err != nil { return err } return c.JSON(http.StatusOK, trigger) } // GetAllUpgradeTriggers handles GET /api/subscription/upgrade-triggers/ func (h *SubscriptionHandler) GetAllUpgradeTriggers(c echo.Context) error { triggers, err := h.subscriptionService.GetAllUpgradeTriggers() if err != nil { return err } return c.JSON(http.StatusOK, triggers) } // GetFeatureBenefits handles GET /api/subscription/features/ func (h *SubscriptionHandler) GetFeatureBenefits(c echo.Context) error { benefits, err := h.subscriptionService.GetFeatureBenefits() if err != nil { return err } return c.JSON(http.StatusOK, benefits) } // GetPromotions handles GET /api/subscription/promotions/ func (h *SubscriptionHandler) GetPromotions(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) promotions, err := h.subscriptionService.GetActivePromotions(user.ID) if err != nil { return err } return c.JSON(http.StatusOK, promotions) } // ProcessPurchase handles POST /api/subscription/purchase/ func (h *SubscriptionHandler) ProcessPurchase(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) var req services.ProcessPurchaseRequest if err := c.Bind(&req); err != nil { return apperrors.BadRequest("error.invalid_request") } var subscription *services.SubscriptionResponse var err error switch req.Platform { case "ios": // StoreKit 2 uses transaction_id, StoreKit 1 uses receipt_data if req.TransactionID == "" && req.ReceiptData == "" { return apperrors.BadRequest("error.receipt_data_required") } subscription, err = h.subscriptionService.ProcessApplePurchase(user.ID, req.ReceiptData, req.TransactionID) case "android": if req.PurchaseToken == "" { return apperrors.BadRequest("error.purchase_token_required") } subscription, err = h.subscriptionService.ProcessGooglePurchase(user.ID, req.PurchaseToken, req.ProductID) } if err != nil { return err } return c.JSON(http.StatusOK, map[string]interface{}{ "message": "message.subscription_upgraded", "subscription": subscription, }) } // CancelSubscription handles POST /api/subscription/cancel/ func (h *SubscriptionHandler) CancelSubscription(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) subscription, err := h.subscriptionService.CancelSubscription(user.ID) if err != nil { return err } return c.JSON(http.StatusOK, map[string]interface{}{ "message": "message.subscription_cancelled", "subscription": subscription, }) } // RestoreSubscription handles POST /api/subscription/restore/ func (h *SubscriptionHandler) RestoreSubscription(c echo.Context) error { user := c.Get(middleware.AuthUserKey).(*models.User) var req services.ProcessPurchaseRequest if err := c.Bind(&req); err != nil { return apperrors.BadRequest("error.invalid_request") } // Same logic as ProcessPurchase - validates receipt/token and restores var subscription *services.SubscriptionResponse var err error switch req.Platform { case "ios": subscription, err = h.subscriptionService.ProcessApplePurchase(user.ID, req.ReceiptData, req.TransactionID) case "android": subscription, err = h.subscriptionService.ProcessGooglePurchase(user.ID, req.PurchaseToken, req.ProductID) } if err != nil { return err } return c.JSON(http.StatusOK, map[string]interface{}{ "message": "message.subscription_restored", "subscription": subscription, }) }