package internal

import (
	"strings"

	"coopcloud.tech/abra/pkg/app"
	"coopcloud.tech/abra/pkg/config"
	"coopcloud.tech/abra/pkg/i18n"
	"coopcloud.tech/abra/pkg/log"
	"coopcloud.tech/abra/pkg/recipe"
	"github.com/AlecAivazis/survey/v2"
)

// ValidateRecipe ensures the recipe arg is valid.
func ValidateRecipe(args []string, cmdName string) recipe.Recipe {
	var recipeName string
	if len(args) > 0 {
		recipeName = args[0]
	}

	var recipes []string

	catl, err := recipe.ReadRecipeCatalogue(Offline)
	if err != nil {
		log.Fatal(err)
	}

	knownRecipes := make(map[string]bool)
	for name := range catl {
		knownRecipes[name] = true
	}

	localRecipes, err := recipe.GetRecipesLocal()
	if err != nil {
		log.Debug(i18n.G("can't read local recipes: %s", err))
	} else {
		for _, recipeLocal := range localRecipes {
			if _, ok := knownRecipes[recipeLocal]; !ok {
				knownRecipes[recipeLocal] = true
			}
		}
	}

	for recipeName := range knownRecipes {
		recipes = append(recipes, recipeName)
	}

	if recipeName == "" && !NoInput {
		prompt := &survey.Select{
			Message: i18n.G("Select recipe"),
			Options: recipes,
		}
		if err := survey.AskOne(prompt, &recipeName); err != nil {
			log.Fatal(err)
		}
	}

	if recipeName == "" {
		log.Fatal(i18n.G("no recipe name provided"))
	}

	if _, ok := knownRecipes[recipeName]; !ok {
		if !strings.Contains(recipeName, "/") {
			log.Fatal(i18n.G("no recipe '%s' exists?", recipeName))
		}
	}

	chosenRecipe := recipe.Get(recipeName)
	if err := chosenRecipe.EnsureExists(); err != nil {
		log.Fatal(err)
	}

	log.Debug(i18n.G("validated %s as recipe argument", recipeName))

	return chosenRecipe
}

// ValidateApp ensures the app name arg is valid.
func ValidateApp(args []string) app.App {
	if len(args) == 0 {
		log.Fatal(i18n.G("no app provided"))
	}

	appName := args[0]

	app, err := app.Get(appName)
	if err != nil {
		log.Fatal(err)
	}

	log.Debug(i18n.G("validated %s as app argument", appName))

	return app
}

// ValidateDomain ensures the domain name arg is valid.
func ValidateDomain(args []string) string {
	var domainName string
	if len(args) > 0 {
		domainName = args[0]
	}

	if domainName == "" && !NoInput {
		prompt := &survey.Input{
			Message: i18n.G("Specify a domain name"),
			Default: "1312.net",
		}
		if err := survey.AskOne(prompt, &domainName); err != nil {
			log.Fatal(err)
		}
	}

	if domainName == "" {
		log.Fatal(i18n.G("no domain provided"))
	}

	log.Debug(i18n.G("validated %s as domain argument", domainName))

	return domainName
}

// ValidateServer ensures the server name arg is valid.
func ValidateServer(args []string) string {
	var serverName string
	if len(args) > 0 {
		serverName = args[0]
	}

	serverNames, err := config.ReadServerNames()
	if err != nil {
		log.Fatal(err)
	}

	if serverName == "" && !NoInput {
		prompt := &survey.Select{
			Message: i18n.G("Specify a server name"),
			Options: serverNames,
		}
		if err := survey.AskOne(prompt, &serverName); err != nil {
			log.Fatal(err)
		}
	}

	matched := false
	for _, name := range serverNames {
		if name == serverName {
			matched = true
		}
	}

	if serverName == "" {
		log.Fatal(i18n.G("no server provided"))
	}

	if !matched {
		log.Fatal(i18n.G("server doesn't exist?"))
	}

	log.Debug(i18n.G("validated %s as server argument", serverName))

	return serverName
}
