package listing

import (
	"net/http"
	"strconv"

	filemodule "hfb_sys/backend/internal/modules/file"
	"hfb_sys/backend/pkg/response"

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

func (h *Handler) ListPublic(c *gin.Context) {
	items, err := h.service.ListPublic(c.Request.Context(), parsePublicListQuery(c))
	if err != nil {
		writeListingError(c, err)
		return
	}
	response.OK(c, items)
}

func (h *Handler) FindPublic(c *gin.Context) {
	id, ok := parseID(c)
	if !ok {
		return
	}
	item, err := h.service.FindPublic(c.Request.Context(), id)
	if err != nil {
		writeListingError(c, err)
		return
	}
	response.OK(c, item)
}

func (h *Handler) Cover(c *gin.Context) {
	id, ok := parseID(c)
	if !ok {
		return
	}
	key, err := h.service.FindPublicCoverKey(c.Request.Context(), id)
	if err != nil {
		writeListingError(c, err)
		return
	}
	h.writePublicObject(c, filemodule.ImageVariantFallbackKeys(key, filemodule.ImageVariantThumb)...)
}

func (h *Handler) Screenshot(c *gin.Context) {
	id, ok := parseID(c)
	if !ok {
		return
	}
	index, err := strconv.Atoi(c.Param("index"))
	if err != nil || index < 0 {
		response.BadRequest(c, "截图序号不正确")
		return
	}
	key, err := h.service.FindPublicScreenshotKey(c.Request.Context(), id, index)
	if err != nil {
		writeListingError(c, err)
		return
	}
	h.writePublicObject(c, filemodule.ImageVariantFallbackKeys(key, filemodule.ImageVariantMedium)...)
}

func (h *Handler) writePublicObject(c *gin.Context, keys ...string) {
	if h.storage == nil {
		response.ServiceUnavailable(c, "文件存储未连接")
		return
	}
	var object *filemodule.Object
	for _, key := range keys {
		nextObject, err := h.storage.Get(c.Request.Context(), key)
		if err == nil {
			object = nextObject
			break
		}
	}
	if object == nil {
		response.Error(c, http.StatusNotFound, "not_found", "图片不存在或暂不可访问")
		return
	}
	defer func() {
		_ = object.Reader.Close()
	}()
	contentType := object.ContentType
	if contentType == "" {
		contentType = "application/octet-stream"
	}
	c.Header("Content-Type", contentType)
	c.Header("Cache-Control", "public, max-age=300")
	c.DataFromReader(http.StatusOK, object.Size, contentType, object.Reader, nil)
}
