package serialization

import (
	"github.com/fox/fox/log"
	"github.com/fox/fox/mapstruct"
	"reflect"
	"time"
)

const (
	timeFormat = "2006-01-02 15:04:05"
)

func time2stringHook(v reflect.Value, _ reflect.StructField) (any, error) {
	if v.Type() == reflect.TypeOf(time.Time{}) {
		if t, ok := v.Interface().(time.Time); ok {
			return t.Format(timeFormat), nil
		}
	}
	return v, nil
}

type resultT[T any] struct {
	ret T
}

func string2timeHook(s string, _ reflect.StructField) (any, error) {
	return time.Parse(timeFormat, s)
}

func StructToMap(_struct interface{}) map[string]interface{} {
	result, err := mapstruct.ToMap(_struct,
		mapstruct.WithTypeHook(reflect.TypeOf(time.Time{}), time2stringHook),
	)
	if err != nil {
		log.ErrorF("struct:%v to map error:%v", _struct, err)
		return make(map[string]interface{})
	}
	return result
}

func MapToStruct[T any](maps map[string]string) (*T, error) {
	result := &resultT[T]{}
	err := mapstruct.ToStruct(maps, &result.ret,
		mapstruct.WithStringTypeHook(reflect.TypeOf(time.Time{}), string2timeHook),
	)
	return &result.ret, err
}
