package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/internal/ai"
	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/internal/config"
	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/internal/system"
	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/internal/tlp"
	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/pkg/types"
	"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/pkg/utils"
)

const (
	appName    = "WiseTLP"
	appVersion = "1.0.0"
	appDesc    = "AI-powered TLP configuration automation tool"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-sigChan
		fmt.Println("\nReceived interrupt signal. Shutting down gracefully...")
		cancel()
	}()

	logger := utils.NewLogger()
	app := &Application{
		ctx:    ctx,
		logger: logger,
		config: config.New(),
	}

	if err := app.Run(); err != nil {
		logger.Error("Application failed", "error", err)
		os.Exit(1)
	}
}

type Application struct {
	ctx    context.Context
	logger *utils.Logger
	config *config.Config
}

func (a *Application) Run() error {
	a.logger.Info("Starting WiseTLP", "version", appVersion)
	a.displayWelcome()

	systemInfo, err := system.DetectSystem(a.ctx)
	if err != nil {
		return fmt.Errorf("failed to detect system: %w", err)
	}

	a.logger.Info("System detected",
		"distro", systemInfo.Distribution,
		"version", systemInfo.Version,
		"arch", systemInfo.Architecture)

	tlpManager := tlp.NewManager(a.logger)
	tlpStatus, err := tlpManager.GetStatus(a.ctx)
	if err != nil {
		return fmt.Errorf("failed to check TLP status: %w", err)
	}

	if !tlpStatus.Installed {
		if err := a.handleTLPInstallation(tlpManager, systemInfo); err != nil {
			return fmt.Errorf("failed to handle TLP installation: %w", err)
		}
	}

	sysInfo, err := system.GatherSystemInfo(a.ctx)
	if err != nil {
		return fmt.Errorf("failed to gather system information: %w", err)
	}

	preferences, err := a.getUserPreferences()
	if err != nil {
		return fmt.Errorf("failed to get user preferences: %w", err)
	}

	aiClient, err := a.configureAIClient()
	if err != nil {
		return fmt.Errorf("failed to configure AI client: %w", err)
	}

	tlpConfig, err := aiClient.GenerateConfig(a.ctx, sysInfo, preferences)
	if err != nil {
		return fmt.Errorf("failed to generate TLP configuration: %w", err)
	}

	if err := a.presentConfiguration(tlpConfig); err != nil {
		return fmt.Errorf("failed to present configuration: %w", err)
	}

	if err := tlpManager.ApplyConfig(a.ctx, tlpConfig); err != nil {
		return fmt.Errorf("failed to apply configuration: %w", err)
	}

	a.logger.Info("TLP configuration applied successfully")
	fmt.Println("\n✓ TLP configuration has been successfully applied!")
	fmt.Println("Your system is now optimized for your specified use case.")

	return nil
}

func (a *Application) displayWelcome() {
	fmt.Printf(`
%s v%s
%s

This tool will help you configure TLP (Linux Advanced Power Management) 
using AI assistance to optimize your system's power management settings.

`, appName, appVersion, appDesc)
}

func (a *Application) handleTLPInstallation(manager *tlp.Manager, sysInfo *system.Info) error {
	fmt.Println("TLP is not installed on your system.")
	fmt.Print("Would you like to install it now? (y/N): ")

	var response string
	fmt.Scanln(&response)

	if response == "y" || response == "Y" || response == "yes" {
		return manager.Install(a.ctx, sysInfo)
	}

	return fmt.Errorf("TLP installation is required to proceed")
}

func (a *Application) getUserPreferences() (*types.UserPreferences, error) {
	return config.GatherUserPreferences()
}

func (a *Application) configureAIClient() (*ai.Client, error) {
	return ai.ConfigureClient(a.logger)
}

func (a *Application) presentConfiguration(config *types.TLPConfiguration) error {
	tlpConfig := &tlp.Configuration{TLPConfiguration: config}
	return tlpConfig.Present()
}
