package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"sync"

	"gopkg.in/yaml.v3"
)

func loadConfig(filename string, config *WindowsConfig) error {
	data, err := os.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("failed to read config file: %w", err)
	}

	if err := yaml.Unmarshal(data, config); err != nil {
		return fmt.Errorf("failed to parse config file: %w", err)
	}

	return nil
}

func processBatchFile(batchFile string) error {
	file, err := os.Open(batchFile)
	if err != nil {
		return fmt.Errorf("failed to open batch file: %w", err)
	}
	defer file.Close()

	var configFiles []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		configFiles = append(configFiles, line)
	}

	if err := scanner.Err(); err != nil {
		return fmt.Errorf("failed to read batch file: %w", err)
	}

	if len(configFiles) == 0 {
		return fmt.Errorf("no config files found in batch file")
	}

	fmt.Printf("Processing %d config files...\n\n", len(configFiles))

	maxConcurrent := 3
	semaphore := make(chan struct{}, maxConcurrent)
	var wg sync.WaitGroup
	var mu sync.Mutex
	results := make(map[string]error)

	for _, configFile := range configFiles {
		wg.Add(1)
		go func(cf string) {
			defer wg.Done()
			semaphore <- struct{}{}
			defer func() { <-semaphore }()

			fmt.Printf("Processing: %s\n", cf)

			config := &WindowsConfig{}
			if err := loadConfig(cf, config); err != nil {
				mu.Lock()
				results[cf] = err
				mu.Unlock()
				fmt.Printf("Error loading %s: %v\n", cf, err)
				return
			}

			if config.VMID == 0 {
				vmid, err := findAvailableVMID(config)
				if err != nil {
					mu.Lock()
					results[cf] = err
					mu.Unlock()
					fmt.Printf("Error finding VM ID for %s: %v\n", cf, err)
					return
				}
				config.VMID = vmid
			}

			if err := createProxmoxWindowsVM(config); err != nil {
				mu.Lock()
				results[cf] = err
				mu.Unlock()
				fmt.Printf("Error creating template from %s: %v\n", cf, err)
				return
			}

			mu.Lock()
			results[cf] = nil
			mu.Unlock()
			fmt.Printf("Successfully created template from %s\n", cf)
		}(configFile)
	}

	wg.Wait()

	fmt.Println("\n========================================")
	fmt.Println("Batch Processing Summary")
	fmt.Println("========================================")

	successCount := 0
	failCount := 0

	for configFile, err := range results {
		if err == nil {
			fmt.Printf("✓ %s - SUCCESS\n", configFile)
			successCount++
		} else {
			fmt.Printf("✗ %s - FAILED: %v\n", configFile, err)
			failCount++
		}
	}

	fmt.Printf("\nTotal: %d | Success: %d | Failed: %d\n", len(configFiles), successCount, failCount)

	if failCount > 0 {
		return fmt.Errorf("%d config(s) failed to process", failCount)
	}

	return nil
}
