package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
	"gitlab.com/pcanilho/go-jira"
	cliErrors "gitlab.com/pcanilho/go-jira-cli/cmd/errors"
	"gitlab.com/pcanilho/go-jira-cli/cmd/helpers"
	"gitlab.com/pcanilho/go-jira-cli/internal"
	"strings"
)

var updateCmd = &cobra.Command{
	Use:   "update",
	Short: "Updates one or multiple issues based on the provided identifiers",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) == 0 {
			return fmt.Errorf("please specify the issue identifier to update")
		}
		for _, issueID := range args {
			issue, err := jiraController.GetIssue(issueID, nil)
			if err != nil {
				return cliErrors.NewCliError(err)
			}

			// Update issue with the provided flags
			toAttach, changelog, err := updateIssueAttributes(issue)
			if err != nil {
				return cliErrors.NewCliError(err)
			}

			// Nothing to update
			if changelog.IsEmpty() {
				helpers.ExitWithMessage(fmt.Sprintf("No change was detected for the ticket {key:[%s], summary: [%s]}...",
					issue.Key, issue.Fields.Summary))
			}

			// Prompt the user before continuing
			if !skipPrompts {
				fmt.Println(changelog)
				confirmed, _ := helpers.PromptToContinue()

				// Abort operation if not confirmed by the user
				if !confirmed {
					helpers.ExitWithAbort()
				}
			}

			// Update issue fields
			_, err = jiraController.UpdateIssue(issue, changelog.ToMap())
			if err != nil {
				return cliErrors.NewCliError(err)
			}

			// Upload attachments
			if err = jiraController.UploadAttachmentsToIssue(issue, toAttach...); err != nil {
				return cliErrors.NewCliError(err)
			}

			// Set output
			output, outputExpanded = issue.Key, issue
		}
		return nil
	},
}

func init() {
	// Update
	updateCmd.Flags().StringVarP(&summary, "summary", "s", "", "the new issue summary")
	updateCmd.Flags().StringArrayVarP(&attachments, "attachment", "a", nil, "attachment(s) to be added to the issue")

	// Add sub-commands
	updateCmd.AddCommand(addCmd)
}

func updateIssueAttributes(issue *jira.Issue) ([]*internal.IssueAttachment, *helpers.ChangeLog, error) {
	changeLog := helpers.NewChangeLog()

	// Summary
	if len(strings.TrimSpace(summary)) > 0 {
		changeLog.AddChange("summary", issue.Fields.Summary, summary, true, true)
	}

	// Attachments
	var issueAttachments []*internal.IssueAttachment
	for _, a := range attachments {
		changeLog.AddChange("Attachment", "", a, false, true)
		attachment, err := attachmentFromPath(a)
		if err != nil {
			return nil, changeLog, err
		}

		issueAttachments = append(issueAttachments, attachment)
	}
	return issueAttachments, changeLog, nil
}