package schema

import (
	"errors"
	"reflect"

	"github.com/sashabaranov/go-openai/jsonschema"
)

type array struct {
	basic

	// items is the schema of the items in the array
	items Type
}

func (a array) SchemaType() jsonschema.DataType {
	return jsonschema.Array
}

func (a array) Definition() jsonschema.Definition {
	def := a.basic.Definition()
	def.Type = jsonschema.Array
	i := a.items.Definition()
	def.Items = &i
	def.AdditionalProperties = false
	return def
}

func (a array) FromAny(val any) (reflect.Value, error) {
	v := reflect.ValueOf(val)

	// first realize we may have a pointer to a slice if this type is not required
	if !a.required && v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Slice {
		return reflect.Value{}, errors.New("expected slice, got " + v.Kind().String())
	}

	// if the slice is nil, we can just return it
	if v.IsNil() {
		return v, nil
	}

	// if the slice is not nil, we need to convert each item
	items := make([]reflect.Value, v.Len())
	for i := 0; i < v.Len(); i++ {
		item, err := a.items.FromAny(v.Index(i).Interface())
		if err != nil {
			return reflect.Value{}, err
		}
		items[i] = item
	}

	return reflect.ValueOf(items), nil
}

func (a array) SetValue(obj reflect.Value, val reflect.Value) {
	if !a.required {
		val = val.Addr()
	}
	obj.Field(a.index).Set(val)
}