package schema

import (
	"gorm.io/gorm/schema"
	"reflect"
	"time"
)

func dataTypeOf(field *schema.Field) string {
	var dataType string
	reflectType := field.FieldType
	for reflectType.Kind() == reflect.Ptr {
		reflectType = reflectType.Elem()
	}
	dataValue := reflect.Indirect(reflect.New(reflectType))
	switch dataValue.Kind() {
	case reflect.Bool:
		dataType = "boolean"
	case reflect.Int8, reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		dataType = "integer"
	case reflect.Float32, reflect.Float64:
		dataType = "double"
	case reflect.Struct:
		if _, ok := dataValue.Interface().(time.Time); ok {
			dataType = "string"
		}
	default:
		dataType = "string"
	}
	return dataType
}

func dataFormatOf(field *schema.Field) string {
	var dataType string
	dataType = field.Tag.Get("format")
	if dataType != "" {
		return dataType
	}
	reflectType := field.FieldType
	for reflectType.Kind() == reflect.Ptr {
		reflectType = reflectType.Elem()
	}
	dataValue := reflect.Indirect(reflect.New(reflectType))
	switch dataValue.Kind() {
	case timeKind, timePtrKind:
		dataType = "datetime"
	case reflect.Bool:
		dataType = "boolean"
	case reflect.Int8, reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		dataType = "integer"
	case reflect.Float32, reflect.Float64:
		dataType = "decimal"
	case reflect.Struct:
		if _, ok := dataValue.Interface().(time.Time); ok {
			dataType = "datetime"
		}
	default:
		dataType = "string"
	}
	return dataType
}
