package core

import (
	"fmt"
	"github.com/gookit/config/v2"
	"reflect"
	"strconv"
	"strings"
)

//var (
//	defaultConfigPath = ".config/spray/"
//	defaultConfigFile = "config.yaml"
//)
//
//func LoadDefault(v interface{}) {
//	dir, err := os.UserHomeDir()
//	if err != nil {
//		logs.Log.Error(err.Error())
//		return
//	}
//	if !files.IsExist(filepath.Join(dir, defaultConfigPath, defaultConfigFile)) {
//		err := os.MkdirAll(filepath.Join(dir, defaultConfigPath), 0o700)
//		if err != nil {
//			logs.Log.Error(err.Error())
//			return
//		}
//		f, err := os.Create(filepath.Join(dir, defaultConfigPath, defaultConfigFile))
//		if err != nil {
//			logs.Log.Error(err.Error())
//			return
//		}
//		err = LoadConfig(filepath.Join(dir, defaultConfigPath, defaultConfigFile), v)
//		if err != nil {
//			logs.Log.Error(err.Error())
//			return
//		}
//		var buf bytes.Buffer
//		_, err = config.DumpTo(&buf, config.Yaml)
//		if err != nil {
//			logs.Log.Error(err.Error())
//			return
//		}
//		fmt.Println(buf.String())
//		f.Sync()
//	}
//}

func LoadConfig(filename string, v interface{}) error {
	err := config.LoadFiles(filename)
	if err != nil {
		return err
	}
	err = config.Decode(v)
	if err != nil {
		return err
	}
	return nil
}

func convertToFieldType(fieldType reflect.StructField, defaultVal string) interface{} {
	switch fieldType.Type.Kind() {
	case reflect.Bool:
		val, err := strconv.ParseBool(defaultVal)
		if err == nil {
			return val
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		val, err := strconv.ParseInt(defaultVal, 10, 64)
		if err == nil {
			return val
		}
	case reflect.Float32, reflect.Float64:
		val, err := strconv.ParseFloat(defaultVal, 64)
		if err == nil {
			return val
		}
	case reflect.String:
		return defaultVal
		// 可以根据需要扩展其他类型
	}
	return nil // 如果转换失败或类型不受支持，返回nil
}

func setFieldValue(field reflect.Value) interface{} {
	switch field.Kind() {
	case reflect.Bool:
		return false
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return 0
	case reflect.Float32, reflect.Float64:
		return 0.0
	case reflect.Slice, reflect.Array:
		return []interface{}{} // 返回一个空切片
	case reflect.String:
		return ""
	case reflect.Struct:
		return make(map[string]interface{})
	default:
		return nil
	}
}

func extractConfigAndDefaults(v reflect.Value, result map[string]interface{}, comments map[string]string) {
	t := v.Type()
	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		fieldType := t.Field(i)
		configTag := fieldType.Tag.Get("config")
		defaultTag := fieldType.Tag.Get("default")
		descriptionTag := fieldType.Tag.Get("description") // 读取description标签

		if configTag != "" {
			var value interface{}
			if defaultTag != "" {
				value = convertToFieldType(fieldType, defaultTag)
			} else {
				value = setFieldValue(field)
			}
			fullPath := configTag // 在递归情况下，您可能需要构建完整的路径
			if field.Kind() == reflect.Struct {
				nestedResult := make(map[string]interface{})
				nestedComments := make(map[string]string)
				extractConfigAndDefaults(field, nestedResult, nestedComments)
				result[configTag] = nestedResult
				for k, v := range nestedComments {
					comments[fullPath+"."+k] = v // 保留嵌套注释的路径
				}
			} else {
				result[configTag] = value
				if descriptionTag != "" {
					comments[fullPath] = descriptionTag
				}
			}
		}
	}
}

func InitDefaultConfig(cfg interface{}, indentLevel int) string {
	var yamlStr strings.Builder
	v := reflect.ValueOf(cfg)
	if v.Kind() == reflect.Ptr {
		v = v.Elem() // 解引用指针
	}
	t := v.Type()

	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		fieldType := t.Field(i)
		configTag := fieldType.Tag.Get("config")
		if configTag == "" {
			continue // 忽略没有config标签的字段
		}

		defaultTag := fieldType.Tag.Get("default")
		descriptionTag := fieldType.Tag.Get("description")

		// 添加注释
		if descriptionTag != "" {
			yamlStr.WriteString(fmt.Sprintf("%s# %s\n", strings.Repeat(" ", indentLevel*2), descriptionTag))
		}

		// 准备值
		valueStr := prepareValue(fieldType.Type.Kind(), defaultTag)

		// 根据字段类型进行处理
		switch field.Kind() {
		case reflect.Struct:
			// 对于嵌套结构体，递归生成YAML
			yamlStr.WriteString(fmt.Sprintf("%s%s:\n%s", strings.Repeat(" ", indentLevel*2), configTag, InitDefaultConfig(field.Interface(), indentLevel+1)))
		default:
			// 直接生成键值对
			yamlStr.WriteString(fmt.Sprintf("%s%s: %s\n", strings.Repeat(" ", indentLevel*2), configTag, valueStr))
		}
	}

	return yamlStr.String()
}

// prepareValue 根据字段类型和default标签的值，准备最终的值字符串
func prepareValue(kind reflect.Kind, defaultVal string) string {
	if defaultVal != "" {
		return defaultVal
	}
	// 根据类型返回默认空值
	switch kind {
	case reflect.Bool:
		return "false"
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return "0"
	case reflect.Float32, reflect.Float64:
		return "0.0"
	case reflect.Slice, reflect.Array:
		return "[]"
	case reflect.String:
		return `""`
	case reflect.Struct, reflect.Map:
		return "{}"
	default:
		return `""`
	}
}
