package http

import (
	"fmt"
	"trustcontact/internal/config"
	"trustcontact/internal/controllers"
	httpmw "trustcontact/internal/http/middleware"
	"trustcontact/internal/services"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/session"
	"gorm.io/gorm"
)

func RegisterRoutes(app *fiber.App, store *session.Store, database *gorm.DB, cfg *config.Config) error {
	app.Static("/static", "web/static")

	app.Use(httpmw.SessionStoreMiddleware(store))
	app.Use(httpmw.CurrentUserMiddleware(store, database))
	app.Use(httpmw.ConsumeFlash())
	app.Use(func(c *fiber.Ctx) error {
		httpmw.SetTemplateData(c, "BuildHash", cfg.BuildHash)
		return c.Next()
	})

	authService, err := services.NewAuthService(database, cfg)
	if err != nil {
		return fmt.Errorf("init auth service: %w", err)
	}
	authController := controllers.NewAuthController(authService)
	usersService := services.NewUsersService(database)
	usersController := controllers.NewUsersController(usersService)
	adminController := controllers.NewAdminController()

	app.Get("/healthz", func(c *fiber.Ctx) error {
		return c.SendStatus(fiber.StatusOK)
	})

	app.Get("/", authController.ShowHome)
	app.Get("/signup", authController.ShowSignup)
	app.Post("/signup", authController.Signup)
	app.Get("/login", authController.ShowLogin)
	app.Post("/login", authController.Login)
	app.Post("/logout", authController.Logout)
	app.Get("/verify-email", authController.VerifyEmail)
	app.Get("/verify-notice", authController.ShowVerifyNotice)
	app.Get("/forgot-password", authController.ShowForgotPassword)
	app.Post("/forgot-password", authController.ForgotPassword)
	app.Get("/reset-password", authController.ShowResetPassword)
	app.Post("/reset-password", authController.ResetPassword)
	app.Get("/forbidden", authController.ShowForbidden)
	app.Get("/welcome", httpmw.RequireAuth(), authController.ShowWelcome)
	app.Post("/preferences/lang", httpmw.RequireAuth(), authController.UpdateLanguage)
	app.Post("/preferences/theme", httpmw.RequireAuth(), authController.UpdateTheme)

	private := app.Group("/private", httpmw.RequireAuth(), httpmw.RequireAdmin())
	private.Get("/", func(c *fiber.Ctx) error {
		return c.Redirect("/admin/users")
	})

	admin := app.Group("/admin", httpmw.RequireAuth(), httpmw.RequireAdmin())
	admin.Get("/", adminController.Dashboard)
	admin.Get("/users", usersController.Index)
	admin.Get("/users/table", usersController.Table)
	admin.Get("/users/:id/modal", usersController.Modal)

	return nil
}
