package server

import (
	"fmt"
	"music-server/cmd/web"
	"net/http"
	"sort"
	"strings"

	_ "music-server/cmd/docs"

	"github.com/a-h/templ"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	echoSwagger "github.com/swaggo/echo-swagger" // echo-swagger middleware
	//_ "github.com/swaggo/echo-swagger/example/docs" // docs is generated by Swag CLI, you have to import it.
)

func (s *Server) RegisterRoutes() http.Handler {
	e := echo.New()
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
		AllowOrigins:     []string{"https://*", "http://*"},
		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
		AllowHeaders:     []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
		AllowCredentials: true,
		MaxAge:           300,
	}))

	fileServer := http.FileServer(http.FS(web.Assets))
	e.GET("/assets/*", echo.WrapHandler(fileServer))

	e.GET("/search", echo.WrapHandler(templ.Handler(web.HelloForm())))
	e.POST("/find", echo.WrapHandler(http.HandlerFunc(web.FindGameWebHandler)))

	e.Static("/", "/frontend")

	swagger := http.FileServer(http.FS(web.Swagger))
	e.GET("/swagger/*", echo.WrapHandler(swagger))

	swaggerRedirect := func(c echo.Context) error {
		return c.Redirect(http.StatusMovedPermanently, "/doc/index.html")
	}
	e.GET("/doc", swaggerRedirect)
	e.GET("/doc/", swaggerRedirect)
	e.GET("/doc/*", echoSwagger.WrapHandler)

	index := NewIndexHandler()
	e.GET("/version", index.GetVersion)
	e.GET("/dbtest", index.GetDBTest)
	e.GET("/health", index.HealthCheck)
	e.GET("/character", index.GetCharacter)
	e.GET("/characters", index.GetCharacters)

	sync := NewSyncHandler()
	syncGroup := e.Group("/sync")
	syncGroup.GET("", sync.SyncGames)
	syncGroup.GET("/new", sync.SyncGamesNewOnlyChanges)
	syncGroup.GET("/new/full", sync.SyncGamesNewFull)
	syncGroup.GET("/quick", sync.SyncGamesQuick)
	syncGroup.GET("/reset", sync.ResetGames)

	music := NewMusicHandler()
	musicGroup := e.Group("/music")
	musicGroup.GET("", music.GetSong)
	musicGroup.GET("/soundTest", music.GetSoundCheckSong)
	musicGroup.GET("/reset", music.ResetMusic)
	musicGroup.GET("/rand", music.GetRandomSong)
	musicGroup.GET("/rand/low", music.GetRandomSongLowChance)
	musicGroup.GET("/rand/classic", music.GetRandomSongClassic)
	musicGroup.GET("/info", music.GetSongInfo)
	musicGroup.GET("/list", music.GetPlayedSongs)
	musicGroup.GET("/next", music.GetNextSong)
	musicGroup.GET("/previous", music.GetPreviousSong)
	musicGroup.GET("/all", music.GetAllGamesRandom)
	musicGroup.GET("/all/order", music.GetAllGames)
	musicGroup.GET("/all/random", music.GetAllGamesRandom)
	musicGroup.PUT("/played", music.PutPlayed)
	musicGroup.GET("/addQue", music.AddLatestToQue)
	musicGroup.GET("/addPlayed", music.AddLatestPlayed)

	routes := e.Routes()
	sort.Slice(routes, func(i, j int) bool {
		return routes[i].Path < routes[j].Path
	})
	for _, r := range routes {
		if (r.Method == "GET" || r.Method == "POST" || r.Method == "PUT" || r.Method == "DELETE") && !strings.Contains(r.Name, "github") {
			fmt.Printf("  %s		%s\n", r.Method, r.Path)
		}
	}
	return e
}
