package commontypes

import "strings"

// GoTypeMap maps PostgreSQL types to Go types
var GoTypeMap = map[string]string{
	// Integer types
	"integer":     "int32",
	"int":         "int32",
	"int4":        "int32",
	"smallint":    "int16",
	"int2":        "int16",
	"bigint":      "int64",
	"int8":        "int64",
	"serial":      "int32",
	"bigserial":   "int64",
	"smallserial": "int16",

	// String types
	"text":      "string",
	"varchar":   "string",
	"char":      "string",
	"character": "string",
	"citext":    "string",
	"bpchar":    "string",

	// Boolean
	"boolean": "bool",
	"bool":    "bool",

	// Float types
	"real":             "float32",
	"float4":           "float32",
	"double precision": "float64",
	"float8":           "float64",
	"numeric":          "float64",
	"decimal":          "float64",

	// Date/Time types
	"timestamp":                   "time.Time",
	"timestamp without time zone": "time.Time",
	"timestamp with time zone":    "time.Time",
	"timestamptz":                 "time.Time",
	"date":                        "time.Time",
	"time":                        "time.Time",
	"time without time zone":      "time.Time",
	"time with time zone":         "time.Time",
	"timetz":                      "time.Time",

	// Binary
	"bytea": "[]byte",

	// UUID
	"uuid": "string",

	// JSON
	"json":  "string",
	"jsonb": "string",

	// Array
	"array": "[]string",
}

// SQLToGo converts SQL types to Go types
func SQLToGo(sqlType string, nullable bool) string {
	baseType := ExtractBaseType(sqlType)

	goType, ok := GoTypeMap[baseType]
	if !ok {
		goType = "interface{}"
	}

	// Handle nullable types
	if nullable {
		return goType
	}

	// For nullable, use pointer types (except for slices and interfaces)
	if !strings.HasPrefix(goType, "[]") && goType != "interface{}" {
		return "*" + goType
	}

	return goType
}

// NeedsTimeImport checks if a Go type requires the time package
func NeedsTimeImport(goType string) bool {
	return strings.Contains(goType, "time.Time")
}
