package anime

import (
	"fmt"
	"mal/internal/server"
	"net/http"
	"strconv"
	"strings"

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

const searchAnimeLimit = 24

type searchItem struct {
	ID          string `json:"id"`
	Type        string `json:"type"`
	Label       string `json:"label"`
	Subtitle    string `json:"subtitle"`
	Href        string `json:"href"`
	Image       string `json:"image,omitempty"`
	Icon        string `json:"icon,omitempty"`
	InWatchlist bool   `json:"inWatchlist,omitempty"`
}

type searchResponse struct {
	Items       []searchItem `json:"items"`
	HasNextPage bool         `json:"hasNextPage"`
	NextPage    int          `json:"nextPage,omitempty"`
}

func (h *AnimeHandler) HandleSearchAPI(c *gin.Context) {
	user := server.CurrentUser(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
		return
	}

	query := strings.TrimSpace(c.Query("q"))
	page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err != nil || page < 1 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid page"})
		return
	}

	if query == "" || len(query) < 2 {
		c.JSON(http.StatusOK, searchResponse{})
		return
	}

	items, hasNextPage := h.searchAnimeResults(c, user.ID, query, page)
	c.JSON(http.StatusOK, searchResponse{
		Items:       items,
		HasNextPage: hasNextPage,
		NextPage:    page + 1,
	})
}

func (h *AnimeHandler) searchAnimeResults(c *gin.Context, userID string, query string, page int) ([]searchItem, bool) {
	res, err := h.svc.SearchAdvanced(c.Request.Context(), query, "", "", "", "", nil, 0, true, page, searchAnimeLimit)
	if err != nil {
		return nil, false
	}

	animes := wrapAnimes(res.Animes)
	watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, animes)
	items := make([]searchItem, 0, len(animes))
	for _, anime := range animes {
		items = append(items, searchItem{
			ID:          fmt.Sprintf("anime:%d", anime.MalID),
			Type:        "anime",
			Label:       anime.DisplayTitle(),
			Subtitle:    strings.TrimSpace("Anime " + anime.Type),
			Href:        fmt.Sprintf("/anime/%d", anime.MalID),
			Image:       anime.ImageURL(),
			InWatchlist: watchlistMap[int64(anime.MalID)],
		})
	}
	return items, res.HasNextPage
}
