package config

import (
	"fmt"
	"path/filepath"

	"github.com/fsnotify/fsnotify"
)

// Watcher represents a configuration file watcher
type Watcher struct {
	watcher    *fsnotify.Watcher
	configPath string
	onReload   func() error
}

// NewWatcher creates a new configuration watcher
func NewWatcher(configPath string, onReload func() error) (*Watcher, error) {
	fsWatcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, fmt.Errorf("failed to create file watcher: %v", err)
	}

	w := &Watcher{
		watcher:    fsWatcher,
		configPath: configPath,
		onReload:   onReload,
	}

	return w, nil
}

// Start begins watching the configuration file for changes
func (w *Watcher) Start() error {
	// Watch the directory containing the config file
	configDir := filepath.Dir(w.configPath)
	if err := w.watcher.Add(configDir); err != nil {
		return fmt.Errorf("failed to watch config directory: %v", err)
	}

	go w.watch()
	return nil
}

// Stop stops watching for configuration changes
func (w *Watcher) Stop() error {
	return w.watcher.Close()
}

func (w *Watcher) watch() {
	for {
		select {
		case event, ok := <-w.watcher.Events:
			if !ok {
				return
			}
			// Check if the config file was modified
			if event.Op&fsnotify.Write == fsnotify.Write &&
				filepath.Base(event.Name) == filepath.Base(w.configPath) {
				if err := w.onReload(); err != nil {
					fmt.Printf("Error reloading config: %v\n", err)
				}
			}
		case err, ok := <-w.watcher.Errors:
			if !ok {
				return
			}
			fmt.Printf("Error watching config file: %v\n", err)
		}
	}
}
