package cmd

import (
	"fmt"
	"log"
	"sort"

	"github.com/insertr/insertr/internal/content"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	timestamp string
	latest    bool
	clean     bool
)

var restoreCmd = &cobra.Command{
	Use:   "restore [site-id]",
	Short: "Restore a site from backup",
	Long: `Restore a registered site from a timestamped backup.

Examples:
  insertr restore demo                    # List available backups
  insertr restore demo --clean           # Restore from oldest backup (cleanest)
  insertr restore demo --latest          # Restore from newest backup  
  insertr restore demo --timestamp 20250910-224704  # Restore from specific backup`,
	Args: cobra.ExactArgs(1),
	Run:  runRestore,
}

func init() {
	restoreCmd.Flags().StringVarP(&timestamp, "timestamp", "t", "", "specific backup timestamp to restore from")
	restoreCmd.Flags().BoolVar(&latest, "latest", false, "restore from most recent backup")
	restoreCmd.Flags().BoolVar(&clean, "clean", false, "restore from oldest backup (cleanest state)")

	// Bind flags to viper
	viper.BindPFlag("restore.timestamp", restoreCmd.Flags().Lookup("timestamp"))
	viper.BindPFlag("restore.latest", restoreCmd.Flags().Lookup("latest"))
	viper.BindPFlag("restore.clean", restoreCmd.Flags().Lookup("clean"))
}

func runRestore(cmd *cobra.Command, args []string) {
	siteID := args[0]

	// Initialize content client (we don't actually need it for restore, but SiteManager expects it)
	contentClient := content.NewMockClient()

	// Initialize site manager
	siteManager := content.NewSiteManager(contentClient, "./insertr-backups", false)

	// Load sites from configuration to register them
	if siteConfigs := viper.Get("server.sites"); siteConfigs != nil {
		if configs, ok := siteConfigs.([]interface{}); ok {
			var sites []*content.SiteConfig
			for _, configInterface := range configs {
				if configMap, ok := configInterface.(map[string]interface{}); ok {
					site := &content.SiteConfig{}
					if id, ok := configMap["site_id"].(string); ok {
						site.SiteID = id
					}
					if path, ok := configMap["path"].(string); ok {
						site.Path = path
					}
					if domain, ok := configMap["domain"].(string); ok {
						site.Domain = domain
					}
					if autoEnhance, ok := configMap["auto_enhance"].(bool); ok {
						site.AutoEnhance = autoEnhance
					}
					if backupOriginals, ok := configMap["backup_originals"].(bool); ok {
						site.BackupOriginals = backupOriginals
					}
					sites = append(sites, site)
				}
			}

			if err := siteManager.RegisterSites(sites); err != nil {
				log.Fatalf("Failed to register sites: %v", err)
			}
		}
	}

	// List available backups
	backups, err := siteManager.ListBackups(siteID)
	if err != nil {
		log.Fatalf("Failed to list backups: %v", err)
	}

	if len(backups) == 0 {
		fmt.Printf("❌ No backups found for site '%s'\n", siteID)
		fmt.Printf("💡 Backups are created automatically during enhancement when backup_originals is enabled\n")
		return
	}

	// Sort backups chronologically
	sort.Strings(backups)

	// Handle different restore modes
	var targetTimestamp string

	if timestamp != "" {
		// Specific timestamp provided
		targetTimestamp = timestamp
		found := false
		for _, backup := range backups {
			if backup == targetTimestamp {
				found = true
				break
			}
		}
		if !found {
			fmt.Printf("❌ Backup timestamp '%s' not found for site '%s'\n", targetTimestamp, siteID)
			fmt.Printf("📋 Available backups:\n")
			for i, backup := range backups {
				if i == 0 {
					fmt.Printf("   %s (oldest/cleanest)\n", backup)
				} else if i == len(backups)-1 {
					fmt.Printf("   %s (newest)\n", backup)
				} else {
					fmt.Printf("   %s\n", backup)
				}
			}
			return
		}
	} else if clean {
		// Restore from oldest backup (cleanest)
		targetTimestamp = backups[0]
		fmt.Printf("🧹 Restoring from oldest backup (cleanest state): %s\n", targetTimestamp)
	} else if latest {
		// Restore from newest backup
		targetTimestamp = backups[len(backups)-1]
		fmt.Printf("🔄 Restoring from newest backup: %s\n", targetTimestamp)
	} else {
		// No specific option - list available backups
		fmt.Printf("📋 Available backups for site '%s':\n", siteID)
		for i, backup := range backups {
			if i == 0 {
				fmt.Printf("   %s (oldest/cleanest) ← use --clean\n", backup)
			} else if i == len(backups)-1 {
				fmt.Printf("   %s (newest) ← use --latest\n", backup)
			} else {
				fmt.Printf("   %s\n", backup)
			}
		}
		fmt.Printf("\nUsage:\n")
		fmt.Printf("   insertr restore %s --clean           # restore from oldest backup\n", siteID)
		fmt.Printf("   insertr restore %s --latest          # restore from newest backup\n", siteID)
		fmt.Printf("   insertr restore %s --timestamp %s   # restore from specific backup\n", siteID, backups[0])
		return
	}

	// Perform restore
	fmt.Printf("🔄 Restoring site '%s' from backup %s...\n", siteID, targetTimestamp)

	if err := siteManager.RestoreFromBackup(siteID, targetTimestamp); err != nil {
		log.Fatalf("❌ Restore failed: %v", err)
	}

	fmt.Printf("✅ Successfully restored site '%s' from backup %s\n", siteID, targetTimestamp)
	fmt.Printf("💡 Site files have been restored to their state from %s\n", targetTimestamp)
}
