package routes

import (
	"sale/internal/api/handlers"
	"sale/internal/api/middlewares"

	"github.com/gin-gonic/gin"
)

func SetupRoutes(r *gin.Engine) {
	authHandler := handlers.NewAuthHandler()
	categoryHandler := handlers.NewCategoryHandler()
	brandHandler := handlers.NewBrandHandler()
	productHandler := handlers.NewProductHandler()
	cartHandler := handlers.NewCartHandler()
	orderHandler := handlers.NewOrderHandler()
	addressHandler := handlers.NewAddressHandler()
	lotteryHandler := handlers.NewLotteryHandler()
	ticketHandler := handlers.NewTicketHandler()
	systemHandler := handlers.NewSystemHandler()
	supplierHandler := handlers.NewSupplierHandler()
	inventoryHandler := handlers.NewInventoryHandler()
	articleHandler := handlers.NewArticleHandler()
	uploadHandler := handlers.NewUploadHandler()
	bannerHandler := handlers.NewBannerHandler()
	paymentChannelHandler := handlers.NewPaymentChannelHandler()
	paymentHandler := handlers.NewPaymentHandler()
	logHandler := handlers.NewLogHandler()

	r.Use(middlewares.CORSMiddleware())

	r.Static("/uploads", "./uploads")
	r.Static("/assets", "./static/assets")
	r.StaticFile("/", "./static/index.html")
	r.StaticFile("/favicon.svg", "./static/favicon.svg")
	r.StaticFile("/icons.svg", "./static/icons.svg")

	r.NoRoute(func(c *gin.Context) {
		c.File("./static/index.html")
	})

	api := r.Group("/api")
	{
		api.GET("/installed", authHandler.CheckInstalled)
		api.POST("/install", authHandler.Install)

		auth := api.Group("/auth")
		{
			auth.POST("/register", authHandler.Register)
			auth.POST("/login", authHandler.Login)
			auth.POST("/forgot-password", authHandler.ForgotPassword)
			auth.POST("/reset-password", authHandler.ResetPassword)
			auth.POST("/verify-email", authHandler.VerifyEmail)
		}

		articles := api.Group("/articles")
		{
			articles.GET("", articleHandler.List)
			articles.GET("/:id", articleHandler.GetByID)
		}

		api.GET("/banners", bannerHandler.List)

		api.GET("/categories", categoryHandler.List)
		api.GET("/brands", brandHandler.List)
		api.GET("/products", productHandler.List)
		api.GET("/products/:id", productHandler.GetByID)
		api.GET("/lotteries", lotteryHandler.List)
		api.GET("/lotteries/:id", lotteryHandler.GetByID)
		api.GET("/settings/public", systemHandler.GetPublicSettings)
		api.GET("/payment-channels", paymentChannelHandler.PublicList)
		api.POST("/payment/bepusdt/notify", paymentHandler.BepUsdtNotify)

		authed := api.Group("")
		authed.Use(middlewares.AuthMiddleware())
		{
			authed.POST("/upload", uploadHandler.UploadImage)
			authed.POST("/upload/multiple", uploadHandler.UploadMultiple)
			authed.DELETE("/upload/:filename", uploadHandler.DeleteImage)

			users := authed.Group("/users")
			{
				users.GET("/profile", authHandler.GetProfile)
				users.PUT("/profile", authHandler.UpdateProfile)
				users.PUT("/password", authHandler.ChangePassword)
				users.POST("/send-verify-code", authHandler.SendVerifyCode)
			}

			addresses := authed.Group("/users/addresses")
			{
				addresses.GET("", addressHandler.List)
				addresses.POST("", addressHandler.Create)
				addresses.PUT("/:id", addressHandler.Update)
				addresses.DELETE("/:id", addressHandler.Delete)
				addresses.PUT("/:id/default", addressHandler.SetDefault)
			}

			carts := authed.Group("/cart")
			{
				carts.GET("", cartHandler.List)
				carts.POST("", cartHandler.Add)
				carts.PUT("/:id", cartHandler.Update)
				carts.DELETE("/:id", cartHandler.Delete)
			}

			orders := authed.Group("/orders")
			{
				orders.GET("", orderHandler.List)
				orders.GET("/:id", orderHandler.GetByID)
				orders.POST("", orderHandler.Create)
				orders.POST("/:id/refund", orderHandler.Refund)
				orders.PUT("/:id/cancel", orderHandler.CancelOrder)
			orders.PUT("/:id/confirm-receipt", orderHandler.ConfirmReceipt)
			orders.POST("/:id/pay", paymentHandler.CreatePayment)
			orders.GET("/:id/payment-status", paymentHandler.CheckPaymentStatus)
			}

			lotteries := authed.Group("/lotteries")
			{
				lotteries.POST("/:id/register", lotteryHandler.Register)
			}

			tickets := authed.Group("/tickets")
			{
				tickets.GET("", ticketHandler.List)
				tickets.POST("", ticketHandler.Create)
				tickets.GET("/:id", ticketHandler.GetByID)
				tickets.POST("/:id/reply", ticketHandler.Reply)
			}

			supplier := authed.Group("/supplier")
			supplier.Use(middlewares.RoleMiddleware("supplier", "admin"))
			{
				supplier.GET("/orders", orderHandler.List)
				supplier.GET("/orders/:id", orderHandler.GetByID)
				supplier.PUT("/orders/:id/confirm", orderHandler.ConfirmOrder)
				supplier.PUT("/orders/:id/ship", orderHandler.ShipOrder)
				supplier.GET("/inventory", inventoryHandler.SupplierList)
				supplier.PUT("/inventory/:id", inventoryHandler.Update)
			}

			admin := authed.Group("/admin")
			admin.Use(middlewares.RoleMiddleware("admin"))
			{
				admin.GET("/stats", systemHandler.GetStats)
			admin.GET("/users", authHandler.AdminGetUsers)
			admin.PUT("/users/:id", authHandler.AdminUpdateUser)
			admin.DELETE("/users/:id", authHandler.AdminDeleteUser)

				adminCategories := admin.Group("/categories")
				{
					adminCategories.POST("", categoryHandler.Create)
					adminCategories.PUT("/:id", categoryHandler.Update)
					adminCategories.DELETE("/:id", categoryHandler.Delete)
				}

				adminBrands := admin.Group("/brands")
				{
					adminBrands.GET("", brandHandler.List)
					adminBrands.POST("", brandHandler.Create)
					adminBrands.PUT("/:id", brandHandler.Update)
					adminBrands.DELETE("/:id", brandHandler.Delete)
				}

				adminProducts := admin.Group("/products")
			{
				adminProducts.GET("", productHandler.AdminList)
				adminProducts.POST("", productHandler.Create)
				adminProducts.PUT("/:id", productHandler.Update)
				adminProducts.DELETE("/:id", productHandler.Delete)
				adminProducts.POST("/:id/custom-fields", productHandler.AddCustomField)
			}

				adminOrders := admin.Group("/orders")
				{
					adminOrders.GET("", orderHandler.AdminList)
					adminOrders.GET("/export", orderHandler.Export)
					adminOrders.PUT("/:id/refund", orderHandler.ProcessRefund)
				}

				adminLotteries := admin.Group("/lotteries")
				{
					adminLotteries.POST("", lotteryHandler.Create)
					adminLotteries.PUT("/:id", lotteryHandler.Update)
					adminLotteries.DELETE("/:id", lotteryHandler.Delete)
					adminLotteries.POST("/:id/prizes", lotteryHandler.AddPrize)
					adminLotteries.POST("/:id/draw", lotteryHandler.Draw)
				}

				adminTickets := admin.Group("/tickets")
				{
					adminTickets.GET("", ticketHandler.AdminList)
					adminTickets.PUT("/:id", ticketHandler.Update)
					adminTickets.PUT("/:id/assign", ticketHandler.Assign)
				}

				admin.GET("/settings", systemHandler.GetSettings)
				admin.PUT("/settings", systemHandler.UpdateSettings)
				admin.PUT("/settings/smtp", systemHandler.UpdateSMTP)
				admin.PUT("/settings/payment", systemHandler.UpdatePayment)

				adminSuppliers := admin.Group("/suppliers")
				{
					adminSuppliers.GET("", supplierHandler.List)
					adminSuppliers.POST("", supplierHandler.Create)
					adminSuppliers.PUT("/:id", supplierHandler.Update)
					adminSuppliers.DELETE("/:id", supplierHandler.Delete)
					adminSuppliers.POST("/:id/authorize", supplierHandler.Authorize)
				}

				admin.GET("/inventory", inventoryHandler.AdminList)

				adminArticles := admin.Group("/articles")
				{
					adminArticles.GET("", articleHandler.AdminList)
					adminArticles.POST("", articleHandler.Create)
					adminArticles.PUT("/:id", articleHandler.Update)
					adminArticles.DELETE("/:id", articleHandler.Delete)
					adminArticles.PUT("/:id/pin", articleHandler.TogglePin)
				}

				adminBanners := admin.Group("/banners")
				{
					adminBanners.GET("", bannerHandler.AdminList)
					adminBanners.POST("", bannerHandler.Create)
					adminBanners.PUT("/:id", bannerHandler.Update)
					adminBanners.DELETE("/:id", bannerHandler.Delete)
					adminBanners.PUT("/:id/toggle", bannerHandler.ToggleActive)
				}

				adminPaymentChannels := admin.Group("/payment-channels")
				{
					adminPaymentChannels.GET("", paymentChannelHandler.List)
					adminPaymentChannels.POST("", paymentChannelHandler.Create)
					adminPaymentChannels.PUT("/:id", paymentChannelHandler.Update)
					adminPaymentChannels.DELETE("/:id", paymentChannelHandler.Delete)
					adminPaymentChannels.PUT("/:id/toggle", paymentChannelHandler.Toggle)
				}

				admin.GET("/logs", logHandler.GetLogs)
				admin.DELETE("/logs", logHandler.ClearLogs)
				admin.GET("/logs/info", logHandler.GetLogInfo)
			}
		}
	}
}
