package config

import (
	"fmt"
	"log/slog"
	"reflect"
	"strings"
	"time"

	"m7s.live/v5/pkg/util"
)

type Property struct {
	Type        string `json:"type"`
	Title       string `json:"title"`
	Description string `json:"description"`
	Enum        []struct {
		Label string `json:"label"`
		Value any    `json:"value"`
	} `json:"enum,omitempty"`
	Items          any            `json:"items,omitempty"`
	Properties     map[string]any `json:"properties,omitempty"`
	Default        any            `json:"default,omitempty"`
	Decorator      string         `json:"x-decorator"`
	DecoratorProps map[string]any `json:"x-decorator-props,omitempty"`
	Component      string         `json:"x-component"`
	ComponentProps map[string]any `json:"x-component-props,omitempty"`
	Index          int            `json:"x-index"`
	// 新增字段：用于前端显示当前值和是否使用默认值
	CurrentValue   any    `json:"x-current-value,omitempty"`   // 当前实际使用的值
	IsDefault      bool   `json:"x-is-default"`                // 是否正在使用默认值
	DefaultValue   any    `json:"x-default-value,omitempty"`   // 默认值
	ValueSource    string `json:"x-value-source,omitempty"`    // 值来源: default, global, file, env, modify
	// 复杂类型显示控制
	ComplexType    string `json:"x-complex-type,omitempty"`    // 复杂类型标识: small-object, large-object, array, map
	FieldCount     int    `json:"x-field-count,omitempty"`     // 字段数量（用于判断是否折叠）
}

type Card struct {
	Type           string         `json:"type"`
	Properties     map[string]any `json:"properties,omitempty"`
	Component      string         `json:"x-component"`
	ComponentProps map[string]any `json:"x-component-props,omitempty"`
	Index          int            `json:"x-index"`
}

// CollapseItem 用于 ArrayCollapse 的 items schema
// ArrayCollapse 组件期望 items['x-component-props'].header 存在
type CollapseItem struct {
	Type           string         `json:"type"`
	Component      string         `json:"x-component"`
	ComponentProps map[string]any `json:"x-component-props,omitempty"`
	Properties     map[string]any `json:"properties,omitempty"`
}

type Object struct {
	Type       string         `json:"type"`
	Properties map[string]any `json:"properties"`
}

// hasNestedComplexType 检查结构体是否包含嵌套的复杂类型（map、slice、struct）
func hasNestedComplexType(t reflect.Type) bool {
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		if !field.IsExported() || field.Tag.Get("yaml") == "-" || field.Anonymous {
			continue
		}
		fieldType := field.Type
		if fieldType.Kind() == reflect.Ptr {
			fieldType = fieldType.Elem()
		}
		switch fieldType.Kind() {
		case reflect.Map, reflect.Slice:
			return true
		case reflect.Struct:
			if fieldType != regexpType && fieldType != durationType {
				return true
			}
		}
	}
	return false
}

// buildFieldProperty 根据字段类型构建 Property
func buildFieldProperty(field reflect.StructField, index int, title string) Property {
	fieldType := field.Type
	if fieldType.Kind() == reflect.Ptr {
		fieldType = fieldType.Elem()
	}
	
	prop := Property{
		Title:     title,
		Decorator: "FormItem",
		Index:     index,
		DecoratorProps: map[string]any{
			"tooltip": field.Tag.Get("desc"),
		},
	}
	
	switch fieldType {
	case durationType:
		prop.Type = "string"
		prop.Component = "Input"
		prop.DecoratorProps["addonAfter"] = "时间,单位：s,m,h,d"
	case regexpType:
		prop.Type = "string"
		prop.Component = "Input"
		prop.DecoratorProps["addonAfter"] = "正则表达式"
	default:
		switch fieldType.Kind() {
		case reflect.Bool:
			prop.Type = "boolean"
			prop.Component = "Switch"
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
			reflect.Float32, reflect.Float64:
			prop.Type = "number"
			prop.Component = "InputNumber"
		default:
			prop.Type = "string"
			prop.Component = "Input"
		}
	}
	
	return prop
}

func (config *Config) schema(index int) (r any) {
	defer func() {
		err := recover()
		if err != nil {
			slog.Error(err.(error).Error())
		}
	}()
	if config.props != nil {
		r := Card{
			Type:       "void",
			Component:  "Card",
			Properties: make(map[string]any),
			Index:      index,
		}
		r.ComponentProps = map[string]any{
			"title": config.name,
		}
		for i, v := range config.props {
			if strings.HasPrefix(v.tag.Get("desc"), "废弃") {
				continue
			}
			r.Properties[v.name] = v.schema(i)
		}
		return r
	} else {
		// 计算值来源和是否使用默认值
		var valueSource string
		var isDefault bool
		if config.Modify != nil {
			valueSource = "modify"
		} else if config.Env != nil {
			valueSource = "env"
		} else if config.File != nil {
			valueSource = "file"
		} else if config.Global != nil {
			valueSource = "global"
		} else {
			valueSource = "default"
			isDefault = true
		}

		p := Property{
			Title:   config.name,
			Default: config.GetValue(),
			DecoratorProps: map[string]any{
				"tooltip": config.tag.Get("desc"),
			},
			ComponentProps: map[string]any{},
			Decorator:      "ConfigFormItem",
			Index:          index,
			// 新增字段
			CurrentValue: config.GetValue(),
			DefaultValue: config.Default,
			IsDefault:    isDefault,
			ValueSource:  valueSource,
		}
		if config.Modify != nil {
			p.Description = "已动态修改"
		} else if config.Env != nil {
			p.Description = "使用环境变量中的值"
		} else if config.File != nil {
			p.Description = "使用配置文件中的值"
		} else if config.Global != nil {
			p.Description = "已使用全局配置中的值"
		}
		p.Enum = config.Enum
		switch config.Ptr.Type() {
		case regexpType:
			p.Type = "string"
			p.Component = "Input"
			p.DecoratorProps["addonAfter"] = "正则表达式"
			str := config.GetValue().(Regexp).String()
			p.ComponentProps = map[string]any{
				"placeholder": str,
			}
			p.Default = str
			p.CurrentValue = str
			if config.Default != nil {
				p.DefaultValue = config.Default.(Regexp).String()
			}
		case durationType:
			p.Type = "string"
			p.Component = "Input"
			str := config.GetValue().(time.Duration).String()
			p.ComponentProps = map[string]any{
				"placeholder": str,
			}
			p.Default = str
			p.CurrentValue = str
			if config.Default != nil {
				p.DefaultValue = config.Default.(time.Duration).String()
			}
			p.DecoratorProps["addonAfter"] = "时间,单位：s,m,h,d，例如：100ms, 10s, 4m, 1h"
		default:
			// 检查是否是 util.Range 类型（泛型类型需要通过类型名称判断）
			typeName := config.Ptr.Type().String()
			if strings.Contains(typeName, "util.Range[") {
				p.Type = "string"
				p.Component = "Input"
				// 将 Range 转换为字符串格式 "min-max"
				str := util.RangeToString(config.Ptr)
				p.ComponentProps = map[string]any{
					"placeholder": str,
				}
				p.Default = str
				p.CurrentValue = str
				if config.Default != nil {
					p.DefaultValue = util.RangeToString(reflect.ValueOf(config.Default))
				}
				p.DecoratorProps["addonAfter"] = "范围，格式：min-max，例如：10001-20000"
				if len(p.Enum) > 0 {
					p.Component = "Radio.Group"
				}
				return p
			}
			switch config.Ptr.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
				p.Type = "number"
				p.Component = "InputNumber"
				p.ComponentProps = map[string]any{
					"placeholder": fmt.Sprintf("%v", config.GetValue()),
				}
			case reflect.Bool:
				p.Type = "boolean"
				p.Component = "Switch"
			case reflect.String:
				p.Type = "string"
				p.Component = "Input"
				p.ComponentProps = map[string]any{
					"placeholder": config.GetValue(),
				}
			case reflect.Slice:
				// 获取 slice 的元素类型
				elemType := config.Ptr.Type().Elem()
				// 如果元素是指针，获取指针指向的类型
				if elemType.Kind() == reflect.Ptr {
					elemType = elemType.Elem()
				}
				elemIsStruct := elemType.Kind() == reflect.Struct && elemType != regexpType
				
				if elemIsStruct {
					// 计算结构体字段数量
					fieldCount := 0
					for i := 0; i < elemType.NumField(); i++ {
						field := elemType.Field(i)
						if field.IsExported() && field.Tag.Get("yaml") != "-" && !field.Anonymous {
							fieldCount++
						}
					}
					
					// 构建 children 数据
					var children []map[string]any
					for i := 0; i < config.Ptr.Len(); i++ {
						elem := config.Ptr.Index(i)
						if elem.Kind() == reflect.Ptr {
							elem = elem.Elem()
						}
						if elem.Kind() == reflect.Struct {
							structMap := make(map[string]any)
							for j := 0; j < elem.NumField(); j++ {
								field := elemType.Field(j)
								if !field.IsExported() || field.Tag.Get("yaml") == "-" || field.Anonymous {
									continue
								}
								fieldName := strings.ToLower(field.Name)
								fieldValue := elem.Field(j)
								if fieldValue.CanInterface() {
									// 特殊处理 time.Duration 类型
									if fieldValue.Type() == durationType {
										structMap[fieldName] = fieldValue.Interface().(time.Duration).String()
									} else {
										structMap[fieldName] = fieldValue.Interface()
									}
								}
							}
							children = append(children, structMap)
						}
					}
					
					// 字段数 > 3 使用 ArrayCards（折叠卡片模式）
					if fieldCount > 3 {
						// 构建卡片内的表单字段
						cardProps := make(map[string]any)
						fieldIndex := 0
						for i := 0; i < elemType.NumField(); i++ {
							field := elemType.Field(i)
							if !field.IsExported() || field.Tag.Get("yaml") == "-" || field.Anonymous {
								continue
							}
							fieldName := strings.ToLower(field.Name)
							fieldDesc := field.Tag.Get("desc")
							if fieldDesc == "" {
								fieldDesc = field.Name
							}
							
							fieldProp := buildFieldProperty(field, fieldIndex, fieldDesc)
							cardProps[fieldName] = fieldProp
							fieldIndex++
						}
						
						p = Property{
							Type:        "array",
							Component:   "ArrayCards",
							Decorator:   "FormItem",
							Title:       config.name,
							Index:       index,
							ComplexType: "array",
							FieldCount:  fieldCount,
							Properties: map[string]any{
								"addition": map[string]any{
									"type":        "void",
									"title":       "添加",
									"x-component": "ArrayCards.Addition",
								},
							},
							Items: &Object{
								Type: "object",
								Properties: map[string]any{
									"index": Card{
										Type:      "void",
										Component: "ArrayCards.Index",
										Index:     0,
									},
									"card": Card{
										Type:      "void",
										Component: "FormLayout",
										ComponentProps: map[string]any{
											"layout":     "vertical",
											"labelCol":   6,
											"wrapperCol": 18,
										},
										Properties: cardProps,
										Index:      1,
									},
									"remove": Card{
										Type:      "void",
										Component: "ArrayCards.Remove",
										Index:     2,
									},
									"moveUp": Card{
										Type:      "void",
										Component: "ArrayCards.MoveUp",
										Index:     3,
									},
									"moveDown": Card{
										Type:      "void",
										Component: "ArrayCards.MoveDown",
										Index:     4,
									},
								},
							},
							Default: children,
						}
						return p
					}
					
					// 字段数 <= 3 使用 ArrayTable（表格模式）
					columnProps := make(map[string]any)
					colIndex := 0
					for i := 0; i < elemType.NumField(); i++ {
						field := elemType.Field(i)
						if !field.IsExported() {
							continue
						}
						// 跳过 gorm 和 yaml:"-" 标记的字段
						if yamlTag := field.Tag.Get("yaml"); yamlTag == "-" {
							continue
						}
						
						fieldName := strings.ToLower(field.Name)
						fieldDesc := field.Tag.Get("desc")
						if fieldDesc == "" {
							fieldDesc = field.Name
						}
						
						// 跳过嵌入的结构体字段（如 config.Pull, config.Record）
						if field.Anonymous {
							continue
						}
						
						// 根据字段类型生成对应的表单组件
						var fieldProp Property
						fieldType := field.Type
						if fieldType.Kind() == reflect.Ptr {
							fieldType = fieldType.Elem()
						}
						
						switch fieldType.Kind() {
						case reflect.Bool:
							fieldProp = Property{
								Type:      "boolean",
								Decorator: "FormItem",
								Component: "Switch",
								Index:     colIndex,
							}
						case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
							reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
							reflect.Float32, reflect.Float64:
							fieldProp = Property{
								Type:      "number",
								Decorator: "FormItem",
								Component: "InputNumber",
								Index:     colIndex,
							}
						default:
							// 默认使用字符串输入框
							fieldProp = Property{
								Type:      "string",
								Decorator: "FormItem",
								Component: "Input",
								Index:     colIndex,
							}
						}
						
						colName := fmt.Sprintf("c%d", colIndex)
						columnProps[colName] = Card{
							Type:      "void",
							Component: "ArrayTable.Column",
							ComponentProps: map[string]any{
								"title": fieldDesc,
							},
							Properties: map[string]any{
								fieldName: fieldProp,
							},
							Index: colIndex,
						}
						colIndex++
					}
					
					// 添加操作列
					columnProps["operator"] = Card{
						Type:      "void",
						Component: "ArrayTable.Column",
						ComponentProps: map[string]any{
							"title": "操作",
							"width": 80,
						},
						Properties: map[string]any{
							"remove": Card{
								Type:      "void",
								Component: "ArrayTable.Remove",
							},
						},
						Index: colIndex,
					}
					
					p = Property{
						Type:        "array",
						Component:   "ArrayTable",
						Decorator:   "FormItem",
						ComplexType: "array",
						FieldCount:  fieldCount,
						Properties: map[string]any{
							"addition": map[string]string{
								"type":        "void",
								"title":       "添加",
								"x-component": "ArrayTable.Addition",
							},
						},
						Index: index,
						Title: config.name,
						Items: &Object{
							Type:       "object",
							Properties: columnProps,
						},
						Default: children,
					}
					return p
				}
				
				// 元素是基本类型，使用简单的 Input
				p.Type = "array"
				p.Component = "Input"
				p.ComponentProps = map[string]any{
					"placeholder": config.GetValue(),
				}
				p.DecoratorProps["addonAfter"] = "数组，每个元素用逗号分隔"
			case reflect.Map:
				// 获取 map 的 key 类型
				keyType := config.Ptr.Type().Key()
				keyIsRegexp := keyType == regexpType
				keyComponent := "Input"
				keyAddonAfter := ""
				if keyIsRegexp {
					keyAddonAfter = "正则表达式"
				}
				
				// 获取 map 的 value 类型
				valueType := config.Ptr.Type().Elem()
				// 如果 value 是指针类型，获取其元素类型
				if valueType.Kind() == reflect.Ptr {
					valueType = valueType.Elem()
				}
				
				// 特殊处理 map[string]any 类型（如 Storage 字段）
				// 使用动态 Schema 注册机制
				if keyType.Kind() == reflect.String && valueType.Kind() == reflect.Interface {
					return buildDynamicStorageSchema(config, index, isDefault, valueSource)
				}
				
				valueIsStruct := valueType.Kind() == reflect.Struct && valueType != regexpType
				valueIsMap := valueType.Kind() == reflect.Map
				
				// 计算 value 的字段数量（用于判断复杂度）
				valueFieldCount := 0
				if valueIsStruct {
					for i := 0; i < valueType.NumField(); i++ {
						field := valueType.Field(i)
						if field.IsExported() && field.Tag.Get("yaml") != "-" && !field.Anonymous {
							valueFieldCount++
						}
					}
				}
				
				// 判断是否是复杂类型（字段数 > 3 或者 value 本身是 map/slice）
				isComplexValue := valueFieldCount > 3 || valueIsMap || (valueIsStruct && hasNestedComplexType(valueType))
				
				// 构建 children 数据
				var children []map[string]any
				iter := config.Ptr.MapRange()
				for iter.Next() {
					// 将 key 转换为字符串（支持 Regexp 类型）
					var keyStr string
					if keyIsRegexp {
						keyStr = iter.Key().Interface().(Regexp).String()
					} else {
						keyStr = fmt.Sprintf("%v", iter.Key().Interface())
					}
					
					// 将 value 转换为适合表单的格式
					var valueForForm any
					val := iter.Value()
					if val.Kind() == reflect.Ptr && !val.IsNil() {
						val = val.Elem()
					}
					if valueIsStruct && val.Kind() == reflect.Struct {
						// 结构体类型，转换为 map
						structMap := make(map[string]any)
						for i := 0; i < val.NumField(); i++ {
							field := valueType.Field(i)
							if !field.IsExported() || field.Tag.Get("yaml") == "-" || field.Anonymous {
								continue
							}
							fieldName := strings.ToLower(field.Name)
							fieldValue := val.Field(i)
							if fieldValue.CanInterface() {
								// 特殊处理 time.Duration 类型
								if fieldValue.Type() == durationType {
									structMap[fieldName] = fieldValue.Interface().(time.Duration).String()
								} else {
									structMap[fieldName] = fieldValue.Interface()
								}
							}
						}
						valueForForm = structMap
					} else {
						if val.CanInterface() {
							valueForForm = val.Interface()
						}
					}
					
					children = append(children, map[string]any{
						"mkey":   keyStr,
						"mvalue": valueForForm,
					})
				}
				
				// 复杂类型使用 ArrayCollapse（折叠面板 + 数组）
				if isComplexValue {
					// 构建 value 的 schema（用于折叠面板内部）
					var valueSchema map[string]any
					if valueIsStruct {
						structProps := make(map[string]any)
						fieldIndex := 0
						for i := 0; i < valueType.NumField(); i++ {
							field := valueType.Field(i)
							if !field.IsExported() || field.Tag.Get("yaml") == "-" || field.Anonymous {
								continue
							}
							fieldName := strings.ToLower(field.Name)
							fieldDesc := field.Tag.Get("desc")
							if fieldDesc == "" {
								fieldDesc = field.Name
							}
							
							fieldProp := buildFieldProperty(field, fieldIndex+2, fieldDesc)
							structProps[fieldName] = fieldProp
							fieldIndex++
						}
						valueSchema = structProps
					}
					
					// 构建 CollapsePanel 内部的 properties
					// 包含：index, mkey, mvalue 字段, remove, moveUp, moveDown
					collapsePanelProps := map[string]any{
						"index": Card{
							Type:      "void",
							Component: "ArrayCollapse.Index",
							Index:     0,
						},
						"mkey": Property{
							Type:      "string",
							Title:     config.tag.Get("key"),
							Decorator: "FormItem",
							Component: keyComponent,
							DecoratorProps: map[string]any{
								"addonAfter": keyAddonAfter,
							},
							Index: 1,
						},
					}
					
					// 添加 mvalue 字段（如果是结构体）
					if valueIsStruct && valueSchema != nil {
						collapsePanelProps["mvalue"] = Card{
							Type:       "object",
							Component:  "FormLayout",
							Properties: valueSchema,
							ComponentProps: map[string]any{
								"layout":     "vertical",
								"labelCol":   6,
								"wrapperCol": 18,
							},
							Index: 2,
						}
					}
					
					// 添加操作按钮
					collapsePanelProps["remove"] = Card{
						Type:      "void",
						Component: "ArrayCollapse.Remove",
						Index:     100,
					}
					collapsePanelProps["moveUp"] = Card{
						Type:      "void",
						Component: "ArrayCollapse.MoveUp",
						Index:     101,
					}
					collapsePanelProps["moveDown"] = Card{
						Type:      "void",
						Component: "ArrayCollapse.MoveDown",
						Index:     102,
					}
					
					// 获取 key 的标题作为 header
					keyTitle := config.tag.Get("key")
					if keyTitle == "" {
						keyTitle = "配置项"
					}
					
					p := Property{
						Type:        "array",
						Component:   "ArrayCollapse",
						Decorator:   "FormItem",
						Title:       config.name,
						Index:       index,
						ComplexType: "map",
						FieldCount:  valueFieldCount,
						IsDefault:   isDefault,
						ValueSource: valueSource,
						ComponentProps: map[string]any{
							"accordion": false,
						},
						Properties: map[string]any{
							"addition": map[string]any{
								"type":        "void",
								"title":       "添加",
								"x-component": "ArrayCollapse.Addition",
							},
						},
						// items 直接就是 CollapsePanel 的 schema
						// ArrayCollapse 组件期望 items['x-component-props'].header 存在
						Items: &CollapseItem{
							Type:       "object",
							Component:  "ArrayCollapse.CollapsePanel",
							Properties: collapsePanelProps,
							ComponentProps: map[string]any{
								"header": keyTitle,
							},
						},
						Default: children,
					}
					return p
				}
				
				// 简单类型继续使用 ArrayTable
				var valueColumnProps map[string]any
				if valueIsStruct {
					// value 是结构体，生成嵌套表单字段
					structProps := make(map[string]any)
					for i := 0; i < valueType.NumField(); i++ {
						field := valueType.Field(i)
						if !field.IsExported() {
							continue
						}
						fieldName := strings.ToLower(field.Name)
						fieldDesc := field.Tag.Get("desc")
						if fieldDesc == "" {
							fieldDesc = field.Name
						}
						
						// 根据字段类型生成对应的表单组件
						var fieldProp Property
						switch field.Type.Kind() {
						case reflect.Bool:
							fieldProp = Property{
								Type:      "boolean",
								Title:     fieldDesc,
								Decorator: "FormItem",
								Component: "Switch",
								Index:     i,
							}
						case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
							reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
							reflect.Float32, reflect.Float64:
							fieldProp = Property{
								Type:      "number",
								Title:     fieldDesc,
								Decorator: "FormItem",
								Component: "InputNumber",
								Index:     i,
							}
						default:
							// 默认使用字符串输入框
							fieldProp = Property{
								Type:      "string",
								Title:     fieldDesc,
								Decorator: "FormItem",
								Component: "Input",
								Index:     i,
							}
						}
						structProps[fieldName] = fieldProp
					}
					valueColumnProps = map[string]any{
						"mvalue": Card{
							Type:       "object",
							Component:  "FormLayout",
							Properties: structProps,
							ComponentProps: map[string]any{
								"layout": "vertical",
							},
						},
					}
				} else {
					// value 是基本类型
					valueColumnProps = map[string]any{
						"mvalue": Property{
							Type:      "string",
							Decorator: "FormItem",
							Component: "Input",
						},
					}
				}
				
				p := Property{
					Type:        "array",
					Component:   "ArrayTable",
					Decorator:   "FormItem",
					ComplexType: "map",
					FieldCount:  valueFieldCount,
					Properties: map[string]any{
						"addition": map[string]string{
							"type":        "void",
							"title":       "添加",
							"x-component": "ArrayTable.Addition",
						},
					},
					Index:       index,
					Title:       config.name,
					IsDefault:   isDefault,
					ValueSource: valueSource,
					Items: &Object{
						Type: "object",
						Properties: map[string]any{
							"c1": Card{
								Type:      "void",
								Component: "ArrayTable.Column",
								ComponentProps: map[string]any{
									"title": config.tag.Get("key"),
									"width": 300,
								},
								Properties: map[string]any{
									"mkey": Property{
										Type:      "string",
										Decorator: "FormItem",
										Component: keyComponent,
										DecoratorProps: map[string]any{
											"addonAfter": keyAddonAfter,
										},
									},
								},
								Index: 0,
							},
							"c2": Card{
								Type:      "void",
								Component: "ArrayTable.Column",
								ComponentProps: map[string]any{
									"title": config.tag.Get("value"),
								},
								Properties: valueColumnProps,
								Index: 1,
							},
							"operator": Card{
								Type:      "void",
								Component: "ArrayTable.Column",
								ComponentProps: map[string]any{
									"title": "操作",
								},
								Properties: map[string]any{
									"remove": Card{
										Type:      "void",
										Component: "ArrayTable.Remove",
									},
								},
								Index: 2,
							},
						},
					},
					Default: children,
				}
				return p
			default:

			}
		}
		if len(p.Enum) > 0 {
			p.Component = "Radio.Group"
		}
		return p
	}
}

// buildNestedTabs 将配置项分组为嵌套 Tab：带子级的各占一个 Tab，顶级配置合并到"基础配置" Tab
func buildNestedTabs(props []*Config, tabPrefix string) map[string]any {
	tabsProps := make(map[string]any)
	
	// 分离带子级的配置和顶级配置
	var nestedProps []*Config  // 带子级的配置
	var basicProps []*Config   // 顶级配置（无子级）
	
	for _, v := range props {
		if len(v.props) > 0 {
			nestedProps = append(nestedProps, v)
		} else {
			basicProps = append(basicProps, v)
		}
	}
	
	tabIndex := 0
	
	// 如果有顶级配置，合并到"基础配置" Tab
	if len(basicProps) > 0 {
		basicTabProps := make(map[string]any)
		for i, v := range basicProps {
			basicTabProps[v.name] = v.schema(i)
		}
		tabsProps[tabPrefix+"_basic"] = Card{
			Type:      "void",
			Component: "FormTab.TabPane",
			ComponentProps: map[string]any{
				"tab": "基础配置",
			},
			Properties: basicTabProps,
			Index:      tabIndex,
		}
		tabIndex++
	}
	
	// 带子级的配置各占一个 Tab
	// 使用 object 类型而不是 void，这样每个 tab 内的字段会有唯一的路径
	// 例如：common_http.listenaddr 和 common_udp.listenaddr 不会冲突
	for _, v := range nestedProps {
		nestedTabProps := make(map[string]any)
		for i, child := range v.props {
			if strings.HasPrefix(child.tag.Get("desc"), "废弃") {
				continue
			}
			nestedTabProps[child.name] = child.schema(i)
		}
		
		// 获取 Tab 标题，优先使用 desc 标签
		tabTitle := v.name
		if desc := v.tag.Get("desc"); desc != "" {
			tabTitle = desc
		}
		
		tabsProps[tabPrefix+"_"+v.name] = Card{
			Type:      "object",  // 使用 object 类型，使字段路径唯一
			Component: "FormTab.TabPane",
			ComponentProps: map[string]any{
				"tab": tabTitle,
			},
			Properties: nestedTabProps,
			Index:      tabIndex,
		}
		tabIndex++
	}
	
	return tabsProps
}

func (config *Config) GetFormily() (r Object) {
	var fromItems = make(map[string]any)
	r.Type = "object"
	r.Properties = map[string]any{
		"layout": Card{
			Type:      "void",
			Component: "FormLayout",
			ComponentProps: map[string]any{
				"labelCol":   4,
				"wrapperCol": 20,
			},
			Properties: fromItems,
		},
	}
	
	// 分离公共配置和插件特有配置
	var commonProps []*Config
	var pluginProps []*Config
	
	// 公共配置字段名列表
	commonFields := map[string]bool{
		"publicip": true, "publicipv6": true, "loglevel": true, "enableauth": true,
		"publish": true, "subscribe": true, "http": true, "quic": true,
		"tcp": true, "udp": true, "hook": true, "pull": true, "transform": true,
		"onsub": true, "onpub": true, "db": true,
	}
	
	for _, v := range config.props {
		if strings.HasPrefix(v.tag.Get("desc"), "废弃") {
			continue
		}
		if commonFields[v.name] {
			commonProps = append(commonProps, v)
		} else {
			pluginProps = append(pluginProps, v)
		}
	}
	
	// 如果既有公共配置又有插件特有配置，使用 Tabs
	if len(commonProps) > 0 && len(pluginProps) > 0 {
		tabsProps := make(map[string]any)
		
		// 插件特有配置 Tab - 内部再用嵌套 Tab
		pluginInnerTabs := buildNestedTabs(pluginProps, "plugin")
		tabsProps["pluginTab"] = Card{
			Type:      "void",
			Component: "FormTab.TabPane",
			ComponentProps: map[string]any{
				"tab": "插件配置",
			},
			Properties: map[string]any{
				"pluginInnerTabs": Card{
					Type:       "void",
					Component:  "FormTab",
					Properties: pluginInnerTabs,
					Index:      0,
				},
			},
			Index: 0,
		}
		
		// 公共配置 Tab - 内部再用嵌套 Tab
		commonInnerTabs := buildNestedTabs(commonProps, "common")
		tabsProps["commonTab"] = Card{
			Type:      "void",
			Component: "FormTab.TabPane",
			ComponentProps: map[string]any{
				"tab": "公共配置",
			},
			Properties: map[string]any{
				"commonInnerTabs": Card{
					Type:       "void",
					Component:  "FormTab",
					Properties: commonInnerTabs,
					Index:      0,
				},
			},
			Index: 1,
		}
		
		fromItems["tabs"] = Card{
			Type:       "void",
			Component:  "FormTab",
			Properties: tabsProps,
			Index:      0,
		}
	} else {
		// 没有分离的情况，使用嵌套 Tab 显示所有配置
		allProps := append(pluginProps, commonProps...)
		innerTabs := buildNestedTabs(allProps, "all")
		fromItems["tabs"] = Card{
			Type:       "void",
			Component:  "FormTab",
			Properties: innerTabs,
			Index:      0,
		}
	}
	return
}

// buildDynamicStorageSchema 为 map[string]any 类型（如 Storage）构建动态表单 Schema
// 使用 DynamicStorage 组件，前端会自动调用 /api/storage/schemas 获取存储类型列表
func buildDynamicStorageSchema(config *Config, index int, isDefault bool, valueSource string) Property {
	// 获取当前配置的值
	currentValue := config.GetValue()
	
	return Property{
		Type:        "object",
		Title:       config.name,
		Decorator:   "FormItem",
		Component:   "DynamicStorage",
		Index:       index,
		Default:     currentValue,
		ComplexType: "dynamic-storage",
		IsDefault:   isDefault,
		ValueSource: valueSource,
		DecoratorProps: map[string]any{
			"tooltip": config.tag.Get("desc"),
		},
		ComponentProps: map[string]any{
			"apiUrl": "/api/storage/schemas",
		},
	}
}
