package main

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

	"chorus.services/bzzz/internal/agent"
	"chorus.services/bzzz/internal/common/runtime"
	"chorus.services/bzzz/logging"
)

// simpleLogger implements the logging.Logger interface
type simpleLogger struct {
	name string
}

func (l *simpleLogger) Info(msg string, args ...interface{}) {
	log.Printf("[INFO] %s: "+msg, append([]interface{}{l.name}, args...)...)
}

func (l *simpleLogger) Warn(msg string, args ...interface{}) {
	log.Printf("[WARN] %s: "+msg, append([]interface{}{l.name}, args...)...)
}

func (l *simpleLogger) Error(msg string, args ...interface{}) {
	log.Printf("[ERROR] %s: "+msg, append([]interface{}{l.name}, args...)...)
}

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

	// Create logger for agent
	logger := &simpleLogger{name: "bzzz-agent"}

	// Create runtime
	rt := runtime.NewRuntime(logger)

	// Initialize shared runtime
	runtimeConfig := runtime.RuntimeConfig{
		ConfigPath:      getConfigPath(),
		BinaryType:      runtime.BinaryTypeAgent,
		EnableSetupMode: needsSetup(),
	}

	// Check for instance collision
	if err := runtime.CheckForRunningInstance("agent", runtime.BinaryTypeAgent); err != nil {
		log.Fatalf("Instance check failed: %v", err)
	}
	defer runtime.RemoveInstanceLock("agent", runtime.BinaryTypeAgent)

	// Initialize runtime services
	services, err := rt.Initialize(ctx, runtimeConfig)
	if err != nil {
		log.Fatalf("Failed to initialize runtime: %v", err)
	}

	// Start shared services
	if err := rt.Start(ctx, services); err != nil {
		log.Fatalf("Failed to start runtime: %v", err)
	}

	// Initialize agent-specific components
	agentRunner := agent.NewRunner(services, logger)
	if err := agentRunner.Start(ctx); err != nil {
		log.Fatalf("Failed to start agent runner: %v", err)
	}

	logger.Info("🤖 BZZZ Autonomous Agent started successfully")
	logger.Info("📍 Node ID: %s", services.Node.ID().ShortString())
	logger.Info("🎯 Agent ID: %s", services.Config.Agent.ID)

	if services.Config.Agent.Role != "" {
		authority, err := services.Config.GetRoleAuthority(services.Config.Agent.Role)
		if err == nil {
			logger.Info("🎭 Role: %s (Authority: %s)", services.Config.Agent.Role, authority)
			if authority == "master" { // Using string literal to avoid import cycle
				logger.Info("👑 This node can become admin/SLURP")
			}
		}
	}

	// Start agent-specific background processes
	startAgentBackgroundProcesses(agentRunner, services, logger)

	logger.Info("✅ Bzzz autonomous agent system fully operational")

	// Wait for shutdown signals
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan

	logger.Info("🛑 Shutting down autonomous agent...")

	// Stop agent runner
	if err := agentRunner.Stop(ctx); err != nil {
		logger.Error("Agent runner shutdown error: %v", err)
	}

	// Stop runtime services
	if err := rt.Stop(ctx, services); err != nil {
		logger.Error("Runtime shutdown error: %v", err)
	}

	logger.Info("✅ Bzzz autonomous agent shutdown completed")
}

// startAgentBackgroundProcesses starts agent-specific background processes
func startAgentBackgroundProcesses(agentRunner *agent.Runner, services *runtime.RuntimeServices, logger logging.Logger) {
	// The agent runner already starts most background processes
	// This function can be used for any additional agent-specific processes

	logger.Info("🔍 Autonomous agent listening for task assignments")
	logger.Info("📡 Ready for P2P task coordination")
	logger.Info("🎯 HMMM collaborative reasoning active")
	logger.Info("🤖 Autonomous task execution enabled")
}

// getConfigPath determines the configuration file path
func getConfigPath() string {
	return runtime.GetConfigPath()
}

// needsSetup checks if the system needs to run setup mode
func needsSetup() bool {
	return runtime.NeedsSetup()
}