package routes

import (
	"gifuu/tools"
	"net/http"
)

func GET_Art_Search(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	query := r.URL.Query()

	paramLimit := tools.ParseLimit(query.Get("limit"))
	paramAfter := tools.ParseSnowflake(query.Get("after"))
	var paramTags []int64

	if params, ok := query["tag"]; ok {
		paramTags = make([]int64, 0, len(params))
		indexTags := make(map[int64]struct{}, len(params))
		for _, raw := range params {
			id := tools.ParseSnowflake(raw)
			if _, exists := indexTags[id]; exists || id == 0 {
				tools.SendClientError(w, r, tools.ERROR_BODY_INVALID_FIELD)
				return
			}
			indexTags[id] = struct{}{}
			paramTags = append(paramTags, id)
		}
	}
	if len(paramTags) == 0 {
		tools.SendClientError(w, r, tools.ERROR_BODY_EMPTY)
		return
	}

	var Results []byte
	err := tools.Database.QueryRow(ctx,
		`SELECT COALESCE(jsonb_agg(t.obj), '[]') FROM (
			SELECT jsonb_build_object(
				'id',     	 u.id::text,
				'created',	 u.created::timestamptz,
				'sticker',	 u.flag_sticker,
				'audio',	 u.flag_audio,
				'framerate', u.encode_fps,
				'width',  	 u.encode_width,
				'height', 	 u.encode_height,
				'rating',	 u.meta_rating,
				'title',  	 u.meta_title,
				'tags',    COALESCE(
					jsonb_agg(
						jsonb_build_object(
							'id',    t.id::text,
							'label', t.label,
							'usage', t.usage
						)
						ORDER BY t.usage DESC
					) FILTER (WHERE t.id IS NOT NULL),
					'[]'
				)
			) AS obj
			FROM gifuu.upload u
			LEFT JOIN gifuu.upload_tag ut ON ut.gif_id = u.id
			LEFT JOIN gifuu.tag t ON t.id = ut.tag_id
			WHERE ut.tag_id = ANY($1::bigint[])
			AND ($2::bigint = 0 OR u.id < $2::bigint)
			AND u.meta_rating < $4
			GROUP BY u.id
			HAVING COUNT(DISTINCT ut.tag_id) = cardinality($1::bigint[])
			ORDER BY u.id DESC
			LIMIT $3::int
		) t`,
		paramTags,
		paramAfter,
		paramLimit,
		tools.MODEL_THRESHOLD_HIDE,
	).Scan(&Results)
	if err != nil {
		tools.SendServerError(w, r, err)
		return
	}

	tools.SendJSON(w, r, http.StatusOK, Results)
}
