package typekit

import (
	"fmt"
	"reflect"
	"sort"
	"strings"
)

const (
	colorReset  = "\033[0m"
	colorStruct = "\033[34m"
	colorField  = "\033[32m"
	colorMap    = "\033[33m"
	colorSlice  = "\033[35m"
	colorValue  = "\033[31m"
	colorKey    = "\033[36m"
)

func PrettyPrint(v interface{}) string {
	return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool)).String()
}

type lines []string

func (l lines) String() string {
	return strings.Join(l, "\n")
}

func prettyPrint(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
	original := v
	// 改进的指针/接口处理逻辑
	for {
		switch v.Kind() {
		case reflect.Ptr:
			if v.IsNil() {
				return lines{colorValue + "nil" + colorReset}
			}
			ptr := v.Pointer() // 使用正确获取指针值的方法
			if visited[ptr] {
				// 正确格式化指针地址
				return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), colorReset)}
			}
			visited[ptr] = true
			original = v
			v = v.Elem()
		case reflect.Interface:
			if v.IsNil() {
				return lines{colorValue + "nil" + colorReset}
			}
			v = v.Elem()
		default:
			goto END_DEREF
		}
	}
END_DEREF:

	switch v.Kind() {
	case reflect.Struct:
		return printStruct(v, indentLevel, visited)
	case reflect.Map:
		return printMap(v, indentLevel, visited)
	case reflect.Slice, reflect.Array:
		return printSlice(v, indentLevel, visited)
	case reflect.String:
		return lines{fmt.Sprintf("%s%q%s", colorValue, v.String(), colorReset)}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Int(), colorReset)}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return lines{fmt.Sprintf("%s%d%s", colorValue, v.Uint(), colorReset)}
	case reflect.Float32, reflect.Float64:
		return lines{fmt.Sprintf("%s%.2f%s", colorValue, v.Float(), colorReset)}
	case reflect.Bool:
		return lines{fmt.Sprintf("%s%t%s", colorValue, v.Bool(), colorReset)}
	default:
		if original.Kind() == reflect.Ptr {
			return lines{fmt.Sprintf("%s%v%s", colorValue, original.Interface(), colorReset)}
		}
		return lines{fmt.Sprintf("%s%v%s", colorValue, v.Interface(), colorReset)}
	}
}

// 完整实现结构体打印
func printStruct(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
	header := fmt.Sprintf("%s%s%s%s:",
		strings.Repeat("  ", indentLevel),
		colorStruct,
		v.Type().String(),
		colorReset,
	)
	result := lines{header}

	for i := 0; i < v.NumField(); i++ {
		field := v.Type().Field(i)
		fieldValue := v.Field(i)

		fieldLines := prettyPrint(fieldValue, indentLevel+1, visited)
		fieldHeader := fmt.Sprintf("%s%s%s: ",
			strings.Repeat("  ", indentLevel+1),
			colorField,
			field.Name,
		)

		if len(fieldLines) == 0 {
			result = append(result, fieldHeader+colorValue+"<invalid>"+colorReset)
			continue
		}

		result = append(result, fieldHeader+fieldLines[0])
		for _, line := range fieldLines[1:] {
			result = append(result,
				strings.Repeat("  ", indentLevel+1)+"  "+line)
		}
	}
	return result
}

// 完整实现map打印
func printMap(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
	header := fmt.Sprintf("%s%s%s%s:",
		strings.Repeat("  ", indentLevel),
		colorMap,
		v.Type().String(),
		colorReset,
	)
	result := lines{header}

	keys := v.MapKeys()
	sort.Slice(keys, func(i, j int) bool {
		return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j])
	})

	for _, key := range keys {
		keyLines := prettyPrint(key, 0, visited)
		valueLines := prettyPrint(v.MapIndex(key), indentLevel+1, visited)

		keyHeader := fmt.Sprintf("%s%s%s: ",
			strings.Repeat("  ", indentLevel+1),
			colorKey,
			strings.Join(keyLines, ""),
		)

		if len(valueLines) == 0 {
			result = append(result, keyHeader+colorValue+"<invalid>"+colorReset)
			continue
		}

		result = append(result, keyHeader+valueLines[0])
		for _, line := range valueLines[1:] {
			result = append(result,
				strings.Repeat("  ", indentLevel+1)+"  "+line)
		}
	}
	return result
}

// 完整实现slice/array打印
func printSlice(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
	header := fmt.Sprintf("%s%s%s%s:",
		strings.Repeat("  ", indentLevel),
		colorSlice,
		v.Type().String(),
		colorReset,
	)
	result := lines{header}

	for i := 0; i < v.Len(); i++ {
		elemLines := prettyPrint(v.Index(i), indentLevel+1, visited)
		bullet := fmt.Sprintf("%s- ",
			strings.Repeat("  ", indentLevel+1),
		)

		if len(elemLines) == 0 {
			result = append(result, bullet+colorValue+"<invalid>"+colorReset)
			continue
		}

		result = append(result, bullet+elemLines[0])
		for _, line := range elemLines[1:] {
			result = append(result,
				strings.Repeat("  ", indentLevel+1)+"  "+line)
		}
	}
	return result
}

/*
// 修正后的测试用例
type Person struct {
	Name    string
	Age     int
	Hobbies []string
	Address struct {
		City  string
		State string
	}
	Metadata map[string]interface{}
}

func main() {
	p := Person{
		Name:    "Alice",
		Age:     30,
		Hobbies: []string{"Reading", "Hiking"},
		Metadata: map[string]interface{}{
			"id":     123,
			"scores": []float64{98.5, 87.2},
			"nested": map[string]interface{}{"a": 1, "b": 2},
		},
	}
	p.Address.City = "New York"
	p.Address.State = "NY"
	p.Metadata["self_ref"] = &p // 正确设置循环引用

	fmt.Println(PrettyPrint(p))
}
*/
