package zciyon

import (
	"bytes"
	"encoding/json"
)

// 未来，path应支持xxx.[0].xxx

// V0.3
func Getstr(dat any, path string, argdef ...string) string {
	defval := ""
	if len(argdef) > 0 {
		defval = argdef[0]
	}
	if arr, ok := dat.(map[string]any); ok {
		return Tostr(arr[path], defval)
	}
	return defval
}
func Getint(dat any, path string, argdef ...int) int {
	defval := 0
	if len(argdef) > 0 {
		defval = argdef[0]
	}
	if arr, ok := dat.(map[string]any); ok {
		return Toint(arr[path], defval)
	}
	return 0
}
func Getfloat(dat any, path string, argdef ...float64) float64 {
	defval := 0.0
	if len(argdef) > 0 {
		defval = argdef[0]
	}
	if arr, ok := dat.(map[string]any); ok {
		return Tofloat(arr[path], defval)
	}
	return 0.0
}
func Getarr(dat any, path ...string) []any {
	if len(path) == 0 {
		if arr, ok := dat.([]any); ok {
			return arr
		}
	} else {
		if arr, ok := dat.(map[string]any); ok {
			if arr2, ok2 := arr[path[0]].([]any); ok2 {
				return arr2
			}
		}
	}
	return []any{}
}
func Getobj(dat any, path ...string) map[string]any {
	if arr, ok := dat.(map[string]any); ok {
		if len(path) > 0 {
			if arr2, ok2 := arr[path[0]].(map[string]any); ok2 {
				return arr2
			}
		} else {
			return arr
		}
	}
	return map[string]any{}
}

func Str_JSON(str string) map[string]any {
	var dat any
	if err := json.Unmarshal([]byte(str), &dat); err != nil {
		return nil
	}
	switch v := dat.(type) {
	case map[string]any:
		return v
	case []any:
		return map[string]any{"arr": v}
	case string:
		return map[string]any{"str": v}
	case float64:
		return map[string]any{"num": v}
	case bool:
		return map[string]any{"bool": v}
	default:
		return map[string]any{"any": v}
	}
}
func Byte_JSON(str []byte) map[string]any {
	var dat any
	if err := json.Unmarshal(str, &dat); err != nil {
		return nil
	}
	switch v := dat.(type) {
	case map[string]any:
		return v
	case []any:
		return map[string]any{"arr": v}
	case string:
		return map[string]any{"str": v}
	case float64:
		return map[string]any{"num": v}
	case bool:
		return map[string]any{"bool": v}
	default:
		return map[string]any{"any": v}
	}
}
func JSON_Byte(dat any) []byte {
	b, err := json.Marshal(dat)
	if err != nil {
		return []byte("{}")
	}
	if bytes.Equal(b, []byte("null")) {
		return []byte("{}")
	}
	return b
}
func JSON_Str(dat any) string {
	b, err := json.Marshal(dat)
	if err != nil {
		return "{}"
	}
	if bytes.Equal(b, []byte("null")) {
		return "{}"
	}
	return string(b)
}

// V0.2
// type ciyJSON struct {
// 	Data any
// }

// func CiyJSON() *ciyJSON {
// 	return &ciyJSON{map[string]any{}}
// }
// func (thos *ciyJSON) Load(str string) error {
// 	if err := json.Unmarshal([]byte(str), &thos.Data); err != nil {
// 		return err
// 	}
// 	return nil
// }
// func (thos *ciyJSON) Parse() string {
// 	b, err := json.Marshal(thos.Data)
// 	if err != nil {
// 		return "{}"
// 	}
// 	if bytes.Equal(b, []byte("null")) {
// 		return "{}"
// 	}
// 	return string(b)
// }
// func (thos *ciyJSON) Getint(path string, argdat ...any) int {
// 	var dat any
// 	if len(argdat) > 0 {
// 		dat = argdat[0]
// 	} else {
// 		dat = thos.Data
// 	}
// 	if arr, ok := dat.(map[string]any); ok {
// 		return Toint(arr[path], 0)
// 	}
// 	return 0
// }
// func (thos *ciyJSON) Getstr(path string, argdat ...any) string {
// 	var dat any
// 	if len(argdat) > 0 {
// 		dat = argdat[0]
// 	} else {
// 		dat = thos.Data
// 	}
// 	if arr, ok := dat.(map[string]any); ok {
// 		return Tostr(arr[path], "")
// 	}
// 	return ""
// }
// func (thos *ciyJSON) Getfloat(path string, argdat ...any) float64 {
// 	var dat any
// 	if len(argdat) > 0 {
// 		dat = argdat[0]
// 	} else {
// 		dat = thos.Data
// 	}
// 	if arr, ok := dat.(map[string]any); ok {
// 		return Tofloat(arr[path], 0.0)
// 	}
// 	return 0.0
// }
// func (thos *ciyJSON) Getarr(path string, argdat ...any) []any {
// 	var dat = thos.Data
// 	if len(argdat) > 0 {
// 		dat = argdat[0]
// 	}
// 	if path == "" {
// 		if arr, ok := dat.([]any); ok {
// 			return arr
// 		}
// 	} else {
// 		if arr, ok := dat.(map[string]any); ok {
// 			if arr2, ok2 := arr[path].([]any); ok2 {
// 				return arr2
// 			}
// 		}
// 	}
// 	return []any{}
// }
// func (thos *ciyJSON) Getobj(path string, argdat ...any) map[string]any {
// 	var dat = thos.Data
// 	if len(argdat) > 0 {
// 		dat = argdat[0]
// 	}
// 	if arr, ok := dat.(map[string]any); ok {
// 		if arr2, ok2 := arr[path].(map[string]any); ok2 {
// 			return arr2
// 		}
// 	}
// 	return map[string]any{}
// }

// V0.1
// type CiyJSON interface {
// 	Load(str string) error
// 	Getint(path string) (int, error)
// 	Getstr(path string) (string, error)
// 	Get(path string) (any, error)
// 	Parse() (string, error)
// }
