package webserver

import (
	"embed"
	"encoding/gob"
	"fmt"
	"html/template"
	"io"
	"io/fs"
	"net/http"
	"strings"
	"time"

	"git.ctdo.de/henne/blitzer-v2/config"
	"git.ctdo.de/henne/blitzer-v2/db"
	"git.ctdo.de/henne/blitzer-v2/webserver/template_functions"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/gorm"
	"github.com/gin-gonic/gin"

	uuid "github.com/satori/go.uuid"
	"github.com/sirupsen/logrus"
)

var (
	templates *template.Template
	//go:embed templates
	templateFS embed.FS
	//go:embed assets
	assetsFS embed.FS
)

func compileTemplates() (*template.Template, error) {
	tpl := template.New("")

	tpl.Funcs(template_functions.FunctionMap)
	err := fs.WalkDir(templateFS, "templates", func(path string, info fs.DirEntry, err error) error {
		if err != nil {
			logrus.Error(err)
			return nil
		}
		if info.IsDir() || !strings.HasSuffix(path, ".html") {
			return nil
		}
		f, _ := templateFS.Open(path)
		sl, _ := io.ReadAll(f)
		name := strings.Split(info.Name(), ".")
		tpl.New(name[0]).Parse(string(sl))
		return nil
	})
	return tpl, err
}

func init() {
	var err error
	templates, err = compileTemplates()
	if err != nil {
		logrus.Error(err)
		panic(1)
	}
}

func ginFormatter(param gin.LogFormatterParams) string {
	if param.Latency > time.Minute {
		// Truncate in a golang < 1.8 safe way
		param.Latency = param.Latency - param.Latency%time.Second
	}
	return fmt.Sprintf("%v | %3d | %13v | %15s | %-7s %#v\n%s",
		param.TimeStamp.Format("2006-01-02 - 15:04:05"),
		param.StatusCode,
		param.Latency,
		param.ClientIP,
		param.Method,
		param.Path,
		param.ErrorMessage,
	)
}

func Init() {
	gob.Register(uuid.UUID{})
	r := gin.New()
	r.Use(gin.LoggerWithFormatter(ginFormatter), gin.Recovery())

	store := gorm.NewStore(db.DB, true, []byte("ctdo"))
	r.Use(sessions.Sessions("blitzer", store))
	var assetsFSSub, _ = fs.Sub(assetsFS, "assets")
	r.StaticFS("assets", http.FS(assetsFSSub))
	r.Static("images", "./images")
	r.GET("", HandleIndex)
	r.GET("setup", HandleSetup)
	r.POST("setup", HandleSetupSave)
	r.GET("test", HandleTest)
	r.GET("ticket/:id/delete", HandleDelete)
	r.GET("ticket/:id", HandleTicket)
	//r.POST("/login", loginHandler)
	//r.GET("/logout", helper.LoggedIn, logoutHandler)

	//event.Init(r.Group("/event"))

	// settings page
	logrus.Fatal(r.Run(fmt.Sprintf("%s:%d", config.C.Web.Host, config.C.Web.Port)))
}
