package cli

import (
	"fmt"
	"os"

	"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/core/ports/driving"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	cfgFile  string
	baseURL  string
	username string
	password string

	// Services injected via constructor - no global state
	services *ServiceContainer
)

// ServiceContainer holds injected services (simple struct - no complex container)
type ServiceContainer struct {
	AppService      driving.AppService
	InstanceService driving.AppInstanceService
	CloudletService driving.CloudletService
}

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "edge-connect",
	Short: "A CLI tool for managing Edge Connect applications",
	Long: `edge-connect is a command line interface for managing Edge Connect applications
and their instances. It provides functionality to create, show, list, and delete
applications and application instances.`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

// ExecuteWithServices executes CLI with dependency-injected services (simple parameter passing)
func ExecuteWithServices(appSvc driving.AppService, instanceSvc driving.AppInstanceService, cloudletSvc driving.CloudletService) {
	// Simple dependency injection - just store services in container
	services = &ServiceContainer{
		AppService:      appSvc,
		InstanceService: instanceSvc,
		CloudletService: cloudletSvc,
	}
	
	Execute()
}

func init() {
	cobra.OnInitialize(initConfig)

	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.edge-connect.yaml)")
	rootCmd.PersistentFlags().StringVar(&baseURL, "base-url", "", "base URL for the Edge Connect API")
	rootCmd.PersistentFlags().StringVar(&username, "username", "", "username for authentication")
	rootCmd.PersistentFlags().StringVar(&password, "password", "", "password for authentication")

	viper.BindPFlag("base_url", rootCmd.PersistentFlags().Lookup("base-url"))
	viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username"))
	viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password"))
}

func initConfig() {
	viper.AutomaticEnv()
	viper.SetEnvPrefix("EDGE_CONNECT")
	viper.BindEnv("base_url", "EDGE_CONNECT_BASE_URL")
	viper.BindEnv("username", "EDGE_CONNECT_USERNAME")
	viper.BindEnv("password", "EDGE_CONNECT_PASSWORD")

	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	} else {
		home, err := os.UserHomeDir()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		viper.AddConfigPath(home)
		viper.SetConfigType("yaml")
		viper.SetConfigName(".edge-connect")
	}

	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}