// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package notifications

import (
	stdctx "context"

	gitea "gitea.dev/sdk"

	"gitea.dev/tea/cmd/flags"
	"gitea.dev/tea/modules/context"
	"gitea.dev/tea/modules/print"
	"github.com/urfave/cli/v3"
)

var notifyFieldsFlag = flags.FieldsFlag(print.NotificationFields, []string{
	"id", "status", "index", "type", "state", "title",
})

var notifyTypeFlag = flags.NewCsvFlag("types", "subject types to filter by", []string{"t"},
	[]string{"issue", "pull", "repository", "commit"}, nil)

// CmdNotificationsList represents a sub command of notifications to list notifications
var CmdNotificationsList = cli.Command{
	Name:        "ls",
	Aliases:     []string{"list"},
	Usage:       "List notifications",
	Description: `List notifications`,
	ArgsUsage:   " ", // command does not accept arguments
	Action:      RunNotificationsList,
	Flags: append([]cli.Flag{
		notifyFieldsFlag,
		notifyTypeFlag,
	}, flags.NotificationFlags...),
}

// RunNotificationsList list notifications
func RunNotificationsList(ctx stdctx.Context, cmd *cli.Command) error {
	var states []gitea.NotifyStatus
	statesStr, err := flags.NotificationStateFlag.GetValues(cmd)
	if err != nil {
		return err
	}
	for _, s := range statesStr {
		states = append(states, gitea.NotifyStatus(s))
	}

	var types []gitea.NotifySubjectType
	typesStr, err := notifyTypeFlag.GetValues(cmd)
	if err != nil {
		return err
	}
	for _, t := range typesStr {
		types = append(types, gitea.NotifySubjectType(t))
	}

	return listNotifications(ctx, cmd, states, types)
}

// listNotifications will get the notifications based on status and subject type
func listNotifications(requestCtx stdctx.Context, cmd *cli.Command, status []gitea.NotifyStatus, subjects []gitea.NotifySubjectType) error {
	var news []*gitea.NotificationThread
	var err error

	ctx, err := context.InitCommand(cmd)
	if err != nil {
		return err
	}
	client := ctx.Login.Client()
	all := ctx.Bool("mine")

	// This enforces pagination (see https://github.com/go-gitea/gitea/issues/16733)
	listOpts := flags.GetListOptions(cmd)
	if listOpts.Page == 0 {
		listOpts.Page = 1
	}

	fields, err := notifyFieldsFlag.GetValues(cmd)
	if err != nil {
		return err
	}

	if all {
		// add repository to the default fields
		if !cmd.IsSet("fields") {
			fields = append(fields, "repository")
		}

		news, _, err = client.Notifications.List(requestCtx, gitea.ListNotificationOptions{
			ListOptions:  listOpts,
			Status:       status,
			SubjectTypes: subjects,
		})
	} else {
		if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
			return err
		}
		news, _, err = client.Notifications.ListByRepo(requestCtx, ctx.Owner, ctx.Repo, gitea.ListNotificationOptions{
			ListOptions:  listOpts,
			Status:       status,
			SubjectTypes: subjects,
		})
	}
	if err != nil {
		return err
	}

	return print.NotificationsList(news, ctx.Output, fields)
}
