package plugins

import (
	"fmt"
	"sort"
	"sync"
)

// Registry manages language plugin registration
type Registry struct {
	mu      sync.RWMutex
	plugins map[string]LanguagePlugin
}

// Global registry instance
var globalRegistry = &Registry{
	plugins: make(map[string]LanguagePlugin),
}

// Register registers a language plugin
func Register(plugin LanguagePlugin) error {
	globalRegistry.mu.Lock()
	defer globalRegistry.mu.Unlock()

	name := plugin.Name()
	if _, exists := globalRegistry.plugins[name]; exists {
		return fmt.Errorf("plugin %s already registered", name)
	}

	globalRegistry.plugins[name] = plugin
	return nil
}

// Get retrieves a plugin by name
func Get(name string) (LanguagePlugin, bool) {
	globalRegistry.mu.RLock()
	defer globalRegistry.mu.RUnlock()

	plugin, ok := globalRegistry.plugins[name]
	return plugin, ok
}

// All returns all registered plugins
func All() []LanguagePlugin {
	globalRegistry.mu.RLock()
	defer globalRegistry.mu.RUnlock()

	plugins := make([]LanguagePlugin, 0, len(globalRegistry.plugins))
	for _, p := range globalRegistry.plugins {
		plugins = append(plugins, p)
	}

	// Sort by name for consistent ordering
	sort.Slice(plugins, func(i, j int) bool {
		return plugins[i].Name() < plugins[j].Name()
	})

	return plugins
}

// Names returns all registered plugin names
func Names() []string {
	globalRegistry.mu.RLock()
	defer globalRegistry.mu.RUnlock()

	names := make([]string, 0, len(globalRegistry.plugins))
	for name := range globalRegistry.plugins {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

// DetectLanguage attempts to detect the language from a path
func DetectLanguage(path string) string {
	globalRegistry.mu.RLock()
	defer globalRegistry.mu.RUnlock()

	// Check marker files for each plugin
	for _, plugin := range globalRegistry.plugins {
		for _, marker := range plugin.MarkerFiles() {
			// Check if marker file exists
			if fileExists(path + "/" + marker) {
				return plugin.Name()
			}
		}
	}

	// Default to first registered plugin
	for name := range globalRegistry.plugins {
		return name
	}

	return ""
}

// GetForExtension returns the plugin for a given file extension
func GetForExtension(ext string) LanguagePlugin {
	globalRegistry.mu.RLock()
	defer globalRegistry.mu.RUnlock()

	for _, plugin := range globalRegistry.plugins {
		for _, pluginExt := range plugin.Extensions() {
			if pluginExt == ext {
				return plugin
			}
		}
	}

	return nil
}

// fileExists is a simple helper - will be replaced with proper implementation
func fileExists(path string) bool {
	// This will be replaced with actual file existence check
	return false
}
