package content

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"github.com/insertr/insertr/internal/engine"
)

// SiteConfig represents configuration for a registered site
type SiteConfig struct {
	SiteID      string `yaml:"site_id"`
	Path        string `yaml:"path"`        // Served path (enhanced output)
	SourcePath  string `yaml:"source_path"` // Source path (for enhancement)
	Domain      string `yaml:"domain,omitempty"`
	AutoEnhance bool   `yaml:"auto_enhance"`
}

// SiteManager handles registration and enhancement of static sites
type SiteManager struct {
	sites    map[string]*SiteConfig
	enhancer *Enhancer
	mutex    sync.RWMutex
	devMode  bool
}

// NewSiteManager creates a new site manager
func NewSiteManager(contentClient engine.ContentClient, devMode bool) *SiteManager {
	return &SiteManager{
		sites:    make(map[string]*SiteConfig),
		enhancer: NewDefaultEnhancer(contentClient, ""), // siteID will be set per operation
		devMode:  devMode,
	}
}

// RegisterSite adds a site to the manager
func (sm *SiteManager) RegisterSite(config *SiteConfig) error {
	sm.mutex.Lock()
	defer sm.mutex.Unlock()

	// Validate site configuration
	if config.SiteID == "" {
		return fmt.Errorf("site_id is required")
	}
	if config.Path == "" {
		return fmt.Errorf("path is required for site %s", config.SiteID)
	}

	// Check if path exists, auto-create enhancement directories
	if _, err := os.Stat(config.Path); os.IsNotExist(err) {
		// Auto-create directory if it appears to be an enhancement target
		if strings.HasSuffix(config.Path, "_enhanced") {
			log.Printf("📁 Creating enhancement directory: %s", config.Path)
			if err := os.MkdirAll(config.Path, 0755); err != nil {
				return fmt.Errorf("failed to create enhancement directory %s: %w", config.Path, err)
			}
		} else {
			return fmt.Errorf("site path does not exist: %s", config.Path)
		}
	}

	// Convert to absolute path
	absPath, err := filepath.Abs(config.Path)
	if err != nil {
		return fmt.Errorf("failed to resolve absolute path for %s: %w", config.Path, err)
	}
	config.Path = absPath

	sm.sites[config.SiteID] = config
	log.Printf("📁 Registered site %s at %s", config.SiteID, config.Path)

	return nil
}

// RegisterSites bulk registers multiple sites from configuration
func (sm *SiteManager) RegisterSites(configs []*SiteConfig) error {
	for _, config := range configs {
		if err := sm.RegisterSite(config); err != nil {
			return fmt.Errorf("failed to register site %s: %w", config.SiteID, err)
		}
	}
	return nil
}

// GetSite returns a registered site configuration
func (sm *SiteManager) GetSite(siteID string) (*SiteConfig, bool) {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	site, exists := sm.sites[siteID]
	return site, exists
}

// GetAllSites returns all registered sites
func (sm *SiteManager) GetAllSites() map[string]*SiteConfig {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	// Return a copy to prevent external modification
	result := make(map[string]*SiteConfig)
	for id, site := range sm.sites {
		result[id] = site
	}
	return result
}

// IsAutoEnhanceEnabled checks if a site has auto-enhancement enabled
func (sm *SiteManager) IsAutoEnhanceEnabled(siteID string) bool {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	site, exists := sm.sites[siteID]
	return exists && site.AutoEnhance
}

// EnhanceSite performs enhancement from source to output directory
func (sm *SiteManager) EnhanceSite(siteID string) error {
	sm.mutex.RLock()
	site, exists := sm.sites[siteID]
	sm.mutex.RUnlock()

	if !exists {
		return fmt.Errorf("site %s is not registered", siteID)
	}

	// Use source path if available, otherwise use main path (for backwards compatibility)
	sourcePath := site.SourcePath
	if sourcePath == "" {
		sourcePath = site.Path
	}
	outputPath := site.Path

	log.Printf("🔄 Enhancing site %s from %s to %s", siteID, sourcePath, outputPath)

	// Create output directory if it doesn't exist
	if err := os.MkdirAll(outputPath, 0755); err != nil {
		return fmt.Errorf("failed to create output directory %s: %w", outputPath, err)
	}

	// Set site ID on enhancer
	sm.enhancer.SetSiteID(siteID)

	// Perform enhancement from source to output
	if err := sm.enhancer.EnhanceDirectory(sourcePath, outputPath); err != nil {
		return fmt.Errorf("failed to enhance site %s: %w", siteID, err)
	}

	log.Printf("✅ Successfully enhanced site %s", siteID)
	return nil
}

// EnhanceAllSites enhances all registered sites that have auto-enhancement enabled
func (sm *SiteManager) EnhanceAllSites() error {
	sm.mutex.RLock()
	sites := make([]*SiteConfig, 0, len(sm.sites))
	for _, site := range sm.sites {
		if site.AutoEnhance {
			sites = append(sites, site)
		}
	}
	sm.mutex.RUnlock()

	var errors []error
	for _, site := range sites {
		if err := sm.EnhanceSite(site.SiteID); err != nil {
			errors = append(errors, err)
		}
	}

	if len(errors) > 0 {
		return fmt.Errorf("enhancement failed for some sites: %v", errors)
	}

	return nil
}

// GetStats returns statistics about registered sites
func (sm *SiteManager) GetStats() map[string]interface{} {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	autoEnhanceCount := 0
	for _, site := range sm.sites {
		if site.AutoEnhance {
			autoEnhanceCount++
		}
	}

	return map[string]interface{}{
		"total_sites":        len(sm.sites),
		"auto_enhance_sites": autoEnhanceCount,
	}
}
