package webui

import (
	"embed"
	"io/fs"
	"net/http"
	"strings"
)

//go:embed all:dist
var distFS embed.FS

// Handler returns an http.Handler that serves the embedded frontend bundle
// (web/dist copied into ./dist by the Dockerfile). Unmatched paths fall back
// to /index.html so TanStack Router's client-side routes (/login, /setup,
// /oauth/callback, …) work on hard-refresh.
//
// In local dev the embed FS is empty (only .gitkeep), so this returns a 404
// for everything; the frontend is served by `vite dev` on :5173 instead.
func Handler() http.Handler {
	sub, err := fs.Sub(distFS, "dist")
	if err != nil {
		// Should be unreachable; the embed dir always exists.
		panic(err)
	}
	fileServer := http.FileServer(http.FS(sub))
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		path := strings.TrimPrefix(r.URL.Path, "/")
		if path == "" {
			path = "index.html"
		}
		// Probe the file. If absent, rewrite to "/" so FileServer serves the
		// SPA index.html.
		served := path
		f, err := sub.Open(path)
		if err != nil {
			r.URL.Path = "/"
			served = "index.html"
		} else {
			_ = f.Close()
		}
		// 缓存策略：embed.FS 无 modtime → 默认不带任何缓存头，浏览器每次都重取
		// （表现为登录跳转回来后 logo 等图片闪烁重载）。按资源类型显式分级：
		//   - /assets/* 是 Vite 带内容哈希的 bundle → 永久不可变缓存
		//   - index.html（含 SPA 回退）必须每次校验，才能在新部署后拉到新哈希
		//   - 其余静态资源（logo / favicon / manifest）极少变 → 一周缓存，
		//     使 logo 仅首访下载一次、后续导航与跨页直接命中缓存、不再重载
		switch {
		case strings.HasPrefix(served, "assets/"):
			w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
		case served == "index.html":
			w.Header().Set("Cache-Control", "no-cache")
		default:
			w.Header().Set("Cache-Control", "public, max-age=604800")
		}
		fileServer.ServeHTTP(w, r)
	})
}
