package repo

import (
	"fmt"
	"strings"

	"code.gitea.io/gitea/modules/convert"

	api "code.gitea.io/gitea/modules/structs"

	"code.gitea.io/gitea/models"
	"code.gitea.io/gitea/modules/context"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/setting"
)

func PublicDatasetMultiple(ctx *context.APIContext) {

	opts := &models.SearchDatasetOptions{
		PublicOnly:     true,
		NeedAttachment: true,
		CloudBrainType: ctx.QueryInt("type"),
	}
	datasetMultiple(ctx, opts)

}

func MyFavoriteDatasetMultiple(ctx *context.APIContext) {

	opts := &models.SearchDatasetOptions{
		StarByMe:       true,
		DatasetIDs:     models.GetDatasetIdsStarByUser(ctx.User.ID),
		NeedAttachment: true,
		CloudBrainType: ctx.QueryInt("type"),
	}
	datasetMultiple(ctx, opts)
}

func CurrentRepoDatasetMultiple(ctx *context.APIContext) {
	datasetIds := models.GetDatasetIdsByRepoID(ctx.Repo.Repository.ID)
	searchOrderBy := getSearchOrderByInValues(datasetIds)
	opts := &models.SearchDatasetOptions{
		RepoID:         ctx.Repo.Repository.ID,
		NeedAttachment: true,
		CloudBrainType: ctx.QueryInt("type"),
		DatasetIDs:     datasetIds,
		SearchOrderBy:  searchOrderBy,
	}

	datasetMultiple(ctx, opts)

}

func MyDatasetsMultiple(ctx *context.APIContext) {

	opts := &models.SearchDatasetOptions{
		UploadAttachmentByMe: true,
		NeedAttachment:       true,
		CloudBrainType:       ctx.QueryInt("type"),
	}
	datasetMultiple(ctx, opts)

}
func datasetMultiple(ctx *context.APIContext, opts *models.SearchDatasetOptions) {
	page := ctx.QueryInt("page")
	if page < 1 {
		page = 1
	}
	pageSize := ctx.QueryInt("pageSize")
	if pageSize < 1 {
		pageSize = setting.UI.DatasetPagingNum
	}

	keyword := strings.Trim(ctx.Query("q"), " ")
	opts.Keyword = keyword
	if opts.SearchOrderBy.String() == "" {
		opts.SearchOrderBy = models.SearchOrderByRecentUpdated
	}

	opts.RecommendOnly = ctx.QueryBool("recommend")
	opts.ListOptions = models.ListOptions{
		Page:     page,
		PageSize: pageSize,
	}
	opts.JustNeedZipFile = true
	opts.User = ctx.User

	datasets, count, err := models.SearchDataset(opts)

	if err != nil {
		log.Error("json.Marshal failed:", err.Error())
		ctx.JSON(200, map[string]interface{}{
			"code":    1,
			"message": err.Error(),
			"data":    []*api.Dataset{},
			"count":   0,
		})
		return
	}
	var convertDatasets []*api.Dataset
	for _, dataset := range datasets {
		convertDatasets = append(convertDatasets, convert.ToDataset(dataset))
	}

	ctx.JSON(200, map[string]interface{}{
		"code":    0,
		"message": "",
		"data":    convertDatasets,
		"count":   count,
	})
}

func getSearchOrderByInValues(datasetIds []int64) models.SearchOrderBy {
	if len(datasetIds) == 0 {
		return ""
	}
	searchOrderBy := "CASE id "
	for i, id := range datasetIds {
		searchOrderBy += fmt.Sprintf(" WHEN %d THEN %d", id, i+1)
	}
	searchOrderBy += " ELSE 0 END"
	return models.SearchOrderBy(searchOrderBy)
}
