package router

import (
	"git.kolaente.de/konrad/Konfi-Castle-Kasino/pkg/broker"
	"html/template"
	"net/http"

	"git.kolaente.de/konrad/Konfi-Castle-Kasino/pkg/config"
	"git.kolaente.de/konrad/Konfi-Castle-Kasino/pkg/models"
	"github.com/gorilla/sessions"
	"github.com/labstack/echo-contrib/session"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/labstack/gommon/log"
)

// NewEcho creates a new echo instance
func NewEcho() *echo.Echo {
	e := echo.New()
	e.HideBanner = true

	//Template
	t := &Template{
		templates: template.Must(template.ParseGlob("tpl/*.html")),
	}
	e.Renderer = t

	//Logger
	e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
		Format: "${time_rfc3339}: ${remote_ip} ${method} ${status} ${uri} - ${user_agent}\n",
	}))

	//log.SetLevel(log.DEBUG)

	// Session middleware
	e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret"))))

	return e
}

// RegisterRoutes registers all routes
func RegisterRoutes(e *echo.Echo) {
	//Static ontent
	e.Static("/assets", "assets")

	//Routes
	e.GET("/", showList)

	e.POST("/login", login)
	e.GET("/logout", logout)

	var handler Handler
	switch config.GetMode() {
	case 0:
		handler = Handler{
			str: func() models.Managable {
				return &models.Kofi{}
			},
		}
	case 1:
		handler = Handler{
			str: func() models.Managable {
				return &models.Community{}
			},
		}
	default:
		log.Fatal("Invalid Mode!")
	}

	// Fancy message broker with SSE
	broker.Init(handler.readAll)
	broker.Start()
	e.GET("/events", broker.Serve)
	e.GET("/list", handler.ReadAll)

	// Routes with auth
	a := e.Group("/admin")
	a.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// Only check if the user is logged in if the path is not /admin, to still be able to show the login page
			if c.Path() != "/admin" && !isLoggedIn(c) {
				return echo.NewHTTPError(http.StatusForbidden, "Login first.")
			}
			return next(c)
		}
	})
	a.GET("", adminHandler)
	a.POST("/update", handler.Update)
	a.POST("/delete", handler.Delete)
	a.POST("/add", handler.Create)
}
