package settings

import (
	"fmt"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

type Settings struct {
	*AppConfig
}

func New(opt ...Option) *Settings {
	opts := new(options)
	for _, o := range opt {
		o(opts)
	}

	opts.repair()

	res := &Settings{
		AppConfig: new(AppConfig),
	}

	mviper := viper.New()
	if opts.name != "" && opts.path != "" && opts.ctype != "" {
		mviper.SetConfigName(opts.name)
		mviper.AddConfigPath(opts.path)
		mviper.SetConfigType(opts.ctype)
	} else {
		mviper.SetConfigFile(opts.name)
	}

	if err := mviper.ReadInConfig(); err != nil {
		fmt.Println(err)
		return nil
	}

	if err := mviper.Unmarshal(&res.AppConfig); err != nil {
		fmt.Println(err)
		return nil
	}

	mviper.WatchConfig()
	mviper.OnConfigChange(func(in fsnotify.Event) {
		if err := mviper.Unmarshal(res.AppConfig); err != nil {
			fmt.Println(err)
		}

		fmt.Println("config change")

		if opts.cb != nil {
			opts.cb(in)
		}
	})

	return res
}
