/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 */
package accountcmd

import (
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

const (
	uuidRegex       = `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`
	defaultHostname = "localhost:1025"
)

func NewAccountUtil() *AccountUtil {
	return &AccountUtil{}
}

type AccountUtil struct {
	createAccountParams CreateAccountParams
	updateAccountParams UpdateAccountParams
	getAccountParams    GetAccountParams
	deleteAccountParams DeleteAccountParams
	listAccountsParams  ListAccountsParams
	commonAccountParams CommonAccountParams
}

type CommonAccountParams struct {
	Username      string
	Password      string
	Hostname      string
	Timeout       uint64
	SkipTLSVerify bool
}

func (util *AccountUtil) MakeAccountCmds() *cobra.Command {
	var subCmd = &cobra.Command{
		Use:     "accounts",
		Short:   "Account operations",
		Aliases: []string{"account"},
	}
	const defaultTimeout uint64 = 10

	subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Username, "user", "U", util.commonAccountParams.Username, "Username")
	subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Password, "pass", "P", util.commonAccountParams.Password, "Password")
	subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Hostname, "host", "X", defaultHostname, "Hostname")
	subCmd.PersistentFlags().Uint64VarP(&util.commonAccountParams.Timeout, "timeout", "T", defaultTimeout, "Operation timeout")
	subCmd.PersistentFlags().BoolVarP(&util.commonAccountParams.SkipTLSVerify, "skipVerify", "S", true, "Skip server certificate verify")
	subCmd.MarkFlagsRequiredTogether("user", "pass")

	vi := viper.New()
	vi.SetEnvPrefix("mstore")
	vi.BindEnv("user")
	vi.BindEnv("pass")
	util.commonAccountParams.Username = vi.GetString("user")
	util.commonAccountParams.Password = vi.GetString("pass")

	// CreateAccount
	var createAccountCmd = &cobra.Command{
		Use:   "create [user:pass@]hostname[:port] username password",
		Short: "Create user account",
		Args:  cobra.ExactArgs(3),
		Run:   util.CreateAccount,
	}
	subCmd.AddCommand(createAccountCmd)

	// GetAccount
	var getAccountCmd = &cobra.Command{
		Use:   "get [user:pass@]hostname[:port] accountId|username",
		Short: "Get account info",
		Args:  cobra.ExactArgs(2),
		Run:   util.GetAccount,
	}
	subCmd.AddCommand(getAccountCmd)

	// UpdateAccount
	var updateAccountCmd = &cobra.Command{
		Use:   "update [user:pass@]hostname[:port] username|accounId",
		Short: "Update account parameters",
		Args:  cobra.ExactArgs(2),
		Run:   util.UpdateAccount,
	}
	updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewUsername, "newname", "u", "", "New username")
	updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewPassword, "newpass", "p", "", "New password")
	updateAccountCmd.MarkFlagsOneRequired("newname", "newpass")
	subCmd.AddCommand(updateAccountCmd)

	// DeleteAccount
	var deleteAccountCmd = &cobra.Command{
		Use:   "delete [user:pass@]hostname[:port] username|accountId",
		Short: "Delete account",
		Args:  cobra.ExactArgs(2),
		Run:   util.DeleteAccount,
	}
	subCmd.AddCommand(deleteAccountCmd)

	// ListAccount
	var listAccountsCmd = &cobra.Command{
		Use:   "list [user:pass@]hostname[:port]",
		Short: "list accounts",
		Args:  cobra.ExactArgs(1),
		Run:   util.ListAccounts,
	}
	listAccountsCmd.Flags().BoolVarP(&util.listAccountsParams.Detail, "detail", "d", false, "Show detail information")
	listAccountsCmd.Flags().StringVarP(&util.listAccountsParams.Regex, "regex", "r", "", "Output regexp for usernames")
	subCmd.AddCommand(listAccountsCmd)

	return subCmd
}
