package chat

import (
	"campaign-pool-be/app/module/chat/controller"
	"campaign-pool-be/app/module/chat/repository"
	"campaign-pool-be/app/module/chat/service"

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

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

// register bulky of Chat module
var NewChatModule = fx.Options(
	// register repository of Chat module
	fx.Provide(repository.NewChatRepository),
	fx.Provide(repository.NewChatScheduleRepository),
	fx.Provide(repository.NewChatScheduleFileRepository),

	// register service of Chat module
	fx.Provide(service.NewChatService),
	fx.Provide(service.NewChatScheduleService),
	fx.Provide(service.NewChatScheduleFileService),

	// register controller of Chat module
	fx.Provide(controller.NewController),
	fx.Provide(controller.NewChatScheduleController),
	fx.Provide(controller.NewChatScheduleFileController),

	// register router of Chat module
	fx.Provide(NewChatRouter),
)

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

// register routes of Chat module
func (_i *ChatRouter) RegisterChatRoutes() {
	// define controllers
	chatController := _i.Controller.Chat
	chatScheduleController := _i.Controller.ChatSchedule
	chatScheduleFileController := _i.Controller.ChatScheduleFile

	// define routes
	_i.App.Route("/chat", func(router fiber.Router) {
		// Chat Session routes
		router.Route("/sessions", func(sessionRouter fiber.Router) {
			sessionRouter.Get("/", chatController.GetAllChatSessions)
			sessionRouter.Get("/:id", chatController.GetChatSessionByID)
			sessionRouter.Post("/", chatController.CreateChatSession)
			sessionRouter.Put("/:id", chatController.UpdateChatSession)
			sessionRouter.Delete("/:id", chatController.DeleteChatSession)

			// Chat Participant routes
			sessionRouter.Post("/:chatSessionId/participants", chatController.AddParticipantToChat)
			sessionRouter.Delete("/:chatSessionId/participants", chatController.RemoveParticipantFromChat)
		})

		// Chat Message routes
		router.Route("/messages", func(messageRouter fiber.Router) {
			messageRouter.Get("/", chatController.GetAllChatMessages)
			messageRouter.Get("/:id", chatController.GetChatMessageByID)
			messageRouter.Post("/", chatController.CreateChatMessage)
			messageRouter.Put("/:id", chatController.UpdateChatMessage)
			messageRouter.Delete("/:id", chatController.DeleteChatMessage)
		})

		// Chat Schedule routes
		router.Route("/schedules", func(scheduleRouter fiber.Router) {
			scheduleRouter.Get("/", chatScheduleController.GetAllChatSchedules)
			scheduleRouter.Get("/upcoming", chatScheduleController.GetUpcomingSchedules)
			scheduleRouter.Get("/status/:status", chatScheduleController.GetSchedulesByStatus)
			scheduleRouter.Get("/:id", chatScheduleController.GetChatScheduleByID)
			scheduleRouter.Post("/", chatScheduleController.CreateChatSchedule)
			scheduleRouter.Put("/:id", chatScheduleController.UpdateChatSchedule)
			scheduleRouter.Delete("/:id", chatScheduleController.DeleteChatSchedule)
			scheduleRouter.Post("/:id/reminder", chatScheduleController.SendScheduleReminder)
		})

		// Chat Schedule File routes
		router.Route("/schedule-files", func(fileRouter fiber.Router) {
			fileRouter.Get("/", chatScheduleFileController.GetChatScheduleFiles)
			fileRouter.Get("/:id", chatScheduleFileController.GetChatScheduleFileByID)
			fileRouter.Post("/:chatScheduleId", chatScheduleFileController.UploadChatScheduleFile)
			fileRouter.Put("/:id", chatScheduleFileController.UpdateChatScheduleFile)
			fileRouter.Delete("/:id", chatScheduleFileController.DeleteChatScheduleFile)
			fileRouter.Get("/viewer/:filename", chatScheduleFileController.Viewer)
		})
	})
}
