package common

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"time"

	"igit.com/xbase/raft"
)

const (
	ColorReset  = "\033[0m"
	ColorDim    = "\033[90m" // Dark Gray
	ColorRed    = "\033[31m"
	ColorGreen  = "\033[32m"
	ColorYellow = "\033[33m"
	ColorBlue   = "\033[34m"
	ColorCyan   = "\033[36m"
)

// Helper to calculate visible length of string ignoring ANSI codes
var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`)

func visibleLen(s string) int {
	clean := ansiRegex.ReplaceAllString(s, "")
	return len([]rune(clean))
}

func printBoxed(content string) {
	lines := strings.Split(strings.TrimSpace(content), "\n")
	maxWidth := 0
	for _, line := range lines {
		l := visibleLen(line)
		if l > maxWidth {
			maxWidth = l
		}
	}
	
	// Min width to look decent
	if maxWidth < 20 {
		maxWidth = 20
	}

	// Add padding
	contentWidth := maxWidth + 2 

	fmt.Println() // Start new line before box
	// Top Border
	fmt.Printf("%s╭%s╮%s\n", ColorDim, strings.Repeat("─", contentWidth), ColorReset)
	
	// Content
	for _, line := range lines {
		visLen := visibleLen(line)
		padding := contentWidth - visLen - 1 // -1 for the space after │
		// Ensure padding is not negative
		if padding < 0 { padding = 0 }
		
		fmt.Printf("%s│%s %s%s%s│%s\n", ColorDim, ColorReset, line, strings.Repeat(" ", padding), ColorDim, ColorReset)
	}
	
	// Bottom Border
	fmt.Printf("%s╰%s╯%s\n", ColorDim, strings.Repeat("─", contentWidth), ColorReset)
	fmt.Println() // End new line after box
}

// RegisterDemoCommands registers the demo commands (demodata, deletedatas) to the CLI
func RegisterDemoCommands(cli *raft.CLI) {
	cli.RegisterCommand("demodata", "Generate n items (e.g. 'demodata 100 user.*')", func(parts []string, server *raft.KVServer) {
		if len(parts) != 3 {
			printBoxed("Usage: demodata <count> <pattern> (e.g. demodata 100 user.*)")
			return
		}
		count, err := strconv.Atoi(parts[1])
		if err != nil {
			printBoxed(fmt.Sprintf("Invalid count: %v", err))
			return
		}
		pattern := parts[2]
		fmt.Printf("Generating %d items with pattern '%s'...\n", count, pattern)
		
		start := time.Now()
		success := 0
		for i := 1; i <= count; i++ {
			key := strings.Replace(pattern, "*", strconv.Itoa(i), -1)
			val := fmt.Sprintf("val-%s", key) // Simple value derivation
			if err := server.Set(key, val); err != nil {
				fmt.Printf("Failed at %d: %v\n", i, err)
			} else {
				success++
			}
			if i%100 == 0 {
				fmt.Printf("Progress: %d/%d\r", i, count)
			}
		}
		duration := time.Since(start)
		printBoxed(fmt.Sprintf("%sDone!%s inserted %d/%d items in %v (Avg: %v/op)", 
			ColorGreen, ColorReset, success, count, duration, duration/time.Duration(count)))
	})

	cli.RegisterCommand("deletedatas", "Batch delete n items matching pattern", func(parts []string, server *raft.KVServer) {
		// deletedatas <n> <pattern>
		if len(parts) != 3 {
			printBoxed("Usage: deletedatas <n> <pattern>")
			return
		}
		n, err := strconv.Atoi(parts[1])
		if err != nil {
			printBoxed("Invalid number: " + parts[1])
			return
		}
		pattern := parts[2]
		
		// Replace * with sequential numbers 1..n
		basePattern := strings.TrimSuffix(pattern, "*")
		
		successCount := 0
		start := time.Now()
		
		fmt.Printf("Deleting up to %d keys matching %s...\n", n, pattern)
		
		for i := 1; i <= n; i++ {
			key := fmt.Sprintf("%s%d", basePattern, i)
			if err := server.Del(key); err == nil {
				successCount++
			}
			if i % 100 == 0 {
				fmt.Print(".")
			}
		}
		fmt.Println()
		
		printBoxed(fmt.Sprintf("%sDeleted %d keys in %v%s", ColorGreen, successCount, time.Since(start), ColorReset))
	})
}
