// Package examples demonstrates BACKBEAT SDK usage patterns
package examples

import (
	"context"
	"crypto/ed25519"
	"crypto/rand"
	"fmt"
	"log/slog"
	"os"
	"os/signal"
	"sync/atomic"
	"syscall"
	"time"

	"github.com/chorus-services/backbeat/pkg/sdk"
)

// SimpleAgent demonstrates basic BACKBEAT SDK usage
// This example shows the minimal integration pattern for CHORUS services
func SimpleAgent() {
	// Generate a signing key for this example
	_, signingKey, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		slog.Error("Failed to generate signing key", "error", err)
		return
	}
	
	// Create SDK configuration
	config := sdk.DefaultConfig()
	config.ClusterID = "chorus-dev"
	config.AgentID = "simple-agent"
	config.NATSUrl = "nats://localhost:4222" // Adjust for your setup
	config.SigningKey = signingKey
	config.Logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		Level: slog.LevelInfo,
	}))
	
	// Create BACKBEAT client
	client := sdk.NewClient(config)
	
	// Track some simple state
	var taskCounter int64
	var completedTasks int64
	
	// Register beat callback - this runs on every beat
	client.OnBeat(func(beat sdk.BeatFrame) {
		currentTasks := atomic.LoadInt64(&taskCounter)
		completed := atomic.LoadInt64(&completedTasks)
		
		// Emit status every few beats
		if beat.BeatIndex%3 == 0 {
			progress := 0.0
			if currentTasks > 0 {
				progress = float64(completed) / float64(currentTasks)
			}
			
			err := client.EmitStatusClaim(sdk.StatusClaim{
				State:     determineState(currentTasks, completed),
				BeatsLeft: calculateBeatsLeft(currentTasks, completed),
				Progress:  progress,
				Notes:     fmt.Sprintf("Processing tasks: %d/%d", completed, currentTasks),
			})
			if err != nil {
				slog.Error("Failed to emit status claim", "error", err)
			}
		}
	})
	
	// Register downbeat callback - this runs at the start of each bar
	client.OnDownbeat(func(beat sdk.BeatFrame) {
		slog.Info("Bar started",
			"beat_index", beat.BeatIndex,
			"window_id", beat.WindowID,
			"phase", beat.Phase)
		
		// Start new tasks at the beginning of bars
		atomic.AddInt64(&taskCounter, 2) // Add 2 new tasks per bar
	})
	
	// Setup graceful shutdown
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	
	// Handle shutdown signals
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	
	go func() {
		<-sigChan
		slog.Info("Shutdown signal received")
		cancel()
	}()
	
	// Start the client
	if err := client.Start(ctx); err != nil {
		slog.Error("Failed to start BACKBEAT client", "error", err)
		return
	}
	defer client.Stop()
	
	slog.Info("Simple agent started - use Ctrl+C to stop")
	
	// Simulate some work - complete tasks periodically
	ticker := time.NewTicker(2 * time.Second)
	defer ticker.Stop()
	
	for {
		select {
		case <-ctx.Done():
			slog.Info("Shutting down simple agent")
			return
		case <-ticker.C:
			// Complete a task if we have any pending
			current := atomic.LoadInt64(&taskCounter)
			completed := atomic.LoadInt64(&completedTasks)
			if completed < current {
				atomic.AddInt64(&completedTasks, 1)
				slog.Debug("Completed a task",
					"completed", completed+1,
					"total", current)
			}
		}
	}
}

// determineState calculates the current state based on task progress
func determineState(total, completed int64) string {
	if total == 0 {
		return "waiting"
	}
	if completed == total {
		return "done"
	}
	if completed > 0 {
		return "executing"
	}
	return "planning"
}

// calculateBeatsLeft estimates beats remaining based on current progress
func calculateBeatsLeft(total, completed int64) int {
	if total == 0 || completed >= total {
		return 0
	}
	
	remaining := total - completed
	// Assume each task takes about 5 beats to complete
	return int(remaining * 5)
}