package workspace

import (
	"fmt"
	"strings"

	"github.com/spf13/cobra"

	"github.com/tidbcloud/aisupport/apps/cli/ticket-manager/common"
	wsapi "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/ticket-manager/workspace"
	wsent "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/entity/ticket-manager/workspace"
)

func newUpdateCommand() *cobra.Command {
	var req wsapi.UpdateWorkspaceRequest
	var rawMembers []string

	cmd := &cobra.Command{
		Use:   "update <workspace-id>",
		Short: "Update a workspace",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			workspaceID := args[0]

			if req.Name == nil && req.Description == nil && req.Severity == nil && req.Members == nil {
				return fmt.Errorf("at least one update field is required")
			}

			var result wsapi.UpdateWorkspaceResponse
			_, err := common.Client.R().
				SetPathParam("id", workspaceID).
				SetBody(&req).
				SetResult(&result).
				Put("/workspace/workspaces/{id}")
			if err != nil {
				return fmt.Errorf("update workspace %s: %w", workspaceID, err)
			}

			return common.Printer.PrintObject(result.Workspace)
		},
	}

	cmd.Flags().String("name", "", "Workspace name")
	cmd.Flags().String("description", "", "Workspace description")
	cmd.Flags().String("severity", "", "Workspace severity")
	cmd.Flags().StringArrayVar(&rawMembers, "member", nil, "Workspace member in email:role:group format")

	cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
		req = wsapi.UpdateWorkspaceRequest{}
		if cmd.Flags().Changed("name") {
			value, err := cmd.Flags().GetString("name")
			if err != nil {
				return err
			}
			req.Name = &value
		}
		if cmd.Flags().Changed("description") {
			value, err := cmd.Flags().GetString("description")
			if err != nil {
				return err
			}
			req.Description = &value
		}
		if cmd.Flags().Changed("severity") {
			value, err := cmd.Flags().GetString("severity")
			if err != nil {
				return err
			}
			severity := wsent.WorkspaceSeverity(value)
			req.Severity = &severity
		}
		if cmd.Flags().Changed("member") {
			values, err := cmd.Flags().GetStringArray("member")
			if err != nil {
				return err
			}
			members, err := parseWorkspaceMembers(values)
			if err != nil {
				return err
			}
			req.Members = &members
		}
		return nil
	}

	return cmd
}

func parseWorkspaceMembers(values []string) ([]wsent.WorkspaceMember, error) {
	members := make([]wsent.WorkspaceMember, 0, len(values))
	for _, value := range values {
		email, rest, ok := strings.Cut(value, ":")
		if !ok {
			return nil, fmt.Errorf("invalid member %q: expected email:role:group", value)
		}
		role, group, ok := strings.Cut(rest, ":")
		if !ok || email == "" || role == "" || group == "" {
			return nil, fmt.Errorf("invalid member %q: expected email:role:group", value)
		}
		members = append(members, wsent.WorkspaceMember{
			Email: email,
			Role:  wsent.WorkspaceMemberRole(role),
			Group: group,
		})
	}
	return members, nil
}
