package ebooks

import (
	"narasi-ahli-be/app/module/ebooks/controller"
	"narasi-ahli-be/app/module/ebooks/repository"
	"narasi-ahli-be/app/module/ebooks/service"

	"github.com/gofiber/fiber/v2"
	"go.uber.org/fx"
)

// EbooksRouter struct of EbooksRouter
type EbooksRouter struct {
	App        fiber.Router
	Controller *Controller
}

// Controller struct for all controllers
type Controller struct {
	Ebooks    controller.EbooksController
	Wishlists controller.EbookWishlistsController
	Purchases controller.EbookPurchasesController
	Ratings   controller.EbookRatingsController
}

// NewEbooksModule register bulky of Ebooks module
var NewEbooksModule = fx.Options(
	// register repository of Ebooks module
	fx.Provide(repository.NewEbooksRepository),
	fx.Provide(repository.NewEbookWishlistsRepository),
	fx.Provide(repository.NewEbookPurchasesRepository),
	fx.Provide(repository.NewEbookRatingsRepository),

	// register service of Ebooks module
	fx.Provide(service.NewEbooksService),
	fx.Provide(service.NewEbookWishlistsService),
	fx.Provide(service.NewEbookPurchasesService),
	fx.Provide(service.NewEbookRatingsService),

	// register controller of Ebooks module
	fx.Provide(controller.NewEbooksController),
	fx.Provide(controller.NewEbookWishlistsController),
	fx.Provide(controller.NewEbookPurchasesController),
	fx.Provide(controller.NewEbookRatingsController),
	fx.Provide(NewController),

	// register router of Ebooks module
	fx.Provide(NewEbooksRouter),
)

// NewController init Controller
func NewController(
	ebooksController controller.EbooksController,
	wishlistsController controller.EbookWishlistsController,
	purchasesController controller.EbookPurchasesController,
	ratingsController controller.EbookRatingsController,
) *Controller {
	return &Controller{
		Ebooks:    ebooksController,
		Wishlists: wishlistsController,
		Purchases: purchasesController,
		Ratings:   ratingsController,
	}
}

// NewEbooksRouter init EbooksRouter
func NewEbooksRouter(fiber *fiber.App, controller *Controller) *EbooksRouter {
	return &EbooksRouter{
		App:        fiber,
		Controller: controller,
	}
}

// RegisterEbooksRoutes register routes of Ebooks module
func (_i *EbooksRouter) RegisterEbooksRoutes() {
	// define controllers
	ebooksController := _i.Controller.Ebooks
	wishlistsController := _i.Controller.Wishlists
	purchasesController := _i.Controller.Purchases
	ratingsController := _i.Controller.Ratings

	// define routes
	_i.App.Route("/ebooks", func(router fiber.Router) {
		// Ebook CRUD routes
		router.Get("/", ebooksController.All)
		router.Get("/slug/:slug", ebooksController.ShowBySlug)
		router.Get("/:id", ebooksController.Show)
		router.Post("/", ebooksController.Save)
		router.Put("/:id", ebooksController.Update)
		router.Delete("/:id", ebooksController.Delete)

		// File upload routes
		router.Post("/pdf/:id", ebooksController.SavePdfFile)
		router.Post("/thumbnail/:id", ebooksController.SaveThumbnail)

		// Download route
		router.Get("/download/:id", ebooksController.DownloadPdf)

		// Statistics route
		router.Get("/statistic/summary", ebooksController.SummaryStats)

		// Wishlist routes
		router.Get("/wishlist", wishlistsController.GetByUserId)
		router.Post("/wishlist/:ebookId", wishlistsController.AddToWishlist)
		router.Delete("/wishlist/:ebookId", wishlistsController.RemoveFromWishlist)
		router.Get("/wishlist/check/:ebookId", wishlistsController.IsInWishlist)

		// Purchase routes
		router.Get("/purchases", purchasesController.GetByBuyerId)
		router.Post("/purchase/:ebookId", purchasesController.PurchaseEbook)
		router.Get("/purchases/:id", purchasesController.GetPurchaseById)
		router.Put("/purchases/:id/payment", purchasesController.UpdatePaymentStatus)
		router.Put("/purchases/:id/confirm", purchasesController.ConfirmPayment)

		// Rating routes
		router.Get("/ratings", ratingsController.GetAll)
		router.Post("/ratings", ratingsController.Create)
		router.Put("/ratings/:id", ratingsController.Update)
		router.Delete("/ratings/:id", ratingsController.Delete)
		router.Get("/ratings/ebook/:id", ratingsController.GetByEbookId)
		router.Get("/ratings/user", ratingsController.GetByUserId)
		router.Get("/ratings/summary/:id", ratingsController.GetEbookRatingSummary)
		router.Get("/ratings/stats/:id", ratingsController.GetRatingStats)
	})
}
