package middleware

import (
	"crypto/subtle"
	"net/http"
	"strings"
	"time"

	"github.com/labstack/echo/v4"
)

const cookieName = "fs_token"

func Auth(token string) echo.MiddlewareFunc {
	if token == "" {
		return func(next echo.HandlerFunc) echo.HandlerFunc {
			return func(c echo.Context) error {
				return next(c)
			}
		}
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// 1. Authorization header（API 调用，首选）
			auth := c.Request().Header.Get("Authorization")
			if len(auth) >= 7 && strings.HasPrefix(auth, "Bearer ") &&
				subtle.ConstantTimeCompare([]byte(auth[7:]), []byte(token)) == 1 {
				setAuthCookie(c, token)
				return next(c)
			}
			// 2. Cookie（<img>/<video> 等浏览器自动携带）
			if ck, err := c.Cookie(cookieName); err == nil &&
				subtle.ConstantTimeCompare([]byte(ck.Value), []byte(token)) == 1 {
				return next(c)
			}
			// 3. 查询参数（兼容旧版，可后续移除）
			if qt := c.QueryParam("token"); qt != "" &&
				subtle.ConstantTimeCompare([]byte(qt), []byte(token)) == 1 {
				setAuthCookie(c, token)
				return next(c)
			}
			return c.JSON(http.StatusUnauthorized, map[string]string{
				"error": "unauthorized",
			})
		}
	}
}

// setAuthCookie 首次认证成功后设置 Cookie（供 <img> 等浏览器请求自动携带）
func setAuthCookie(c echo.Context, token string) {
	c.SetCookie(&http.Cookie{
		Name:     cookieName,
		Value:    token,
		Path:     "/",
		MaxAge:   int(24 * time.Hour / time.Second),
		HttpOnly: true,
		Secure:   c.Request().TLS != nil,
		SameSite: http.SameSiteLaxMode,
	})
}
