package static

import (
	"embed"
	"io/fs"
	"mime"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	content embed.FS
}

func New(content embed.FS) *Handler {
	return &Handler{content: content}
}

func (h *Handler) Register(r *gin.Engine) {
	sub, err := fs.Sub(h.content, "dist")
	if err != nil {
		sub = h.content
	}
	r.NoRoute(func(c *gin.Context) {
		if strings.HasPrefix(c.Request.URL.Path, "/api/") || strings.HasPrefix(c.Request.URL.Path, "/v1/") {
			c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
			return
		}
		h.serve(c, sub)
	})
	r.GET("/", func(c *gin.Context) { h.serve(c, sub) })
	r.GET("/assets/*filepath", func(c *gin.Context) { h.serve(c, sub) })
}

func (h *Handler) serve(c *gin.Context, sub fs.FS) {
	path := strings.TrimPrefix(c.Request.URL.Path, "/")
	if path == "" {
		path = "index.html"
	}
	data, err := fs.ReadFile(sub, path)
	if err != nil {
		data, err = fs.ReadFile(sub, "index.html")
		if err != nil {
			c.String(http.StatusNotFound, "UI not built. Run: make build-web")
			return
		}
		path = "index.html"
	}
	ext := filepath.Ext(path)
	ct := mime.TypeByExtension(ext)
	if ct == "" {
		ct = "text/html"
	}
	if strings.HasPrefix(path, "assets/") {
		c.Header("Cache-Control", "public, max-age=31536000, immutable")
	} else {
		c.Header("Cache-Control", "no-cache")
	}
	c.Data(http.StatusOK, ct, data)
}
