package internal

import (
	"errors"
	"strings"

	"coopcloud.tech/abra/pkg/app"
	"coopcloud.tech/abra/pkg/catalogue"
	"coopcloud.tech/abra/pkg/config"
	"coopcloud.tech/abra/pkg/recipe"
	"github.com/AlecAivazis/survey/v2"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli/v2"
)

// ValidateRecipe ensures the recipe arg is valid.
func ValidateRecipe(c *cli.Context) recipe.Recipe {
	recipeName := c.Args().First()

	if recipeName == "" {
		ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
	}

	recipe, err := recipe.Get(recipeName)
	if err != nil {
		logrus.Fatal(err)
	}

	logrus.Debugf("validated '%s' as recipe argument", recipeName)

	return recipe
}

// ValidateRecipeWithPrompt ensures a recipe argument is present before
// validating, asking for input if required.
func ValidateRecipeWithPrompt(c *cli.Context) recipe.Recipe {
	recipeName := c.Args().First()

	if recipeName == "" && !NoInput {
		catl, err := catalogue.ReadRecipeCatalogue()
		if err != nil {
			logrus.Fatal(err)
		}
		var recipes []string
		for name := range catl {
			recipes = append(recipes, name)
		}
		prompt := &survey.Select{
			Message: "Select recipe",
			Options: recipes,
		}
		if err := survey.AskOne(prompt, &recipeName); err != nil {
			logrus.Fatal(err)
		}
	}

	if recipeName == "" {
		ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
	}

	recipe, err := recipe.Get(recipeName)
	if err != nil {
		logrus.Fatal(err)
	}

	logrus.Debugf("validated '%s' as recipe argument", recipeName)

	return recipe
}

// ValidateApp ensures the app name arg is valid.
func ValidateApp(c *cli.Context) config.App {
	appName := c.Args().First()

	if appName == "" {
		ShowSubcommandHelpAndError(c, errors.New("no app provided"))
	}

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

	if err := recipe.EnsureExists(app.Type); err != nil {
		logrus.Fatal(err)
	}

	logrus.Debugf("validated '%s' as app argument", appName)

	return app
}

// ValidateDomain ensures the domain name arg is valid.
func ValidateDomain(c *cli.Context) (string, error) {
	domainName := c.Args().First()

	if domainName == "" && !NoInput {
		prompt := &survey.Input{
			Message: "Specify a domain name",
			Default: "example.com",
		}
		if err := survey.AskOne(prompt, &domainName); err != nil {
			return domainName, err
		}
	}

	if domainName == "" {
		ShowSubcommandHelpAndError(c, errors.New("no domain provided"))
	}

	logrus.Debugf("validated '%s' as domain argument", domainName)

	return domainName, nil
}

// ValidateSubCmdFlags ensures flag order conforms to correct order
func ValidateSubCmdFlags(c *cli.Context) bool {
	for argIdx, arg := range c.Args().Slice() {
		if !strings.HasPrefix(arg, "--") {
			for _, flag := range c.Args().Slice()[argIdx:] {
				if strings.HasPrefix(flag, "--") {
					return false
				}
			}
		}
	}
	return true
}