package rest

import (
	"context"
	"strings"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

const runtimeScopedPicklistValidator = "runtime_scoped_picklist"

type runtimePicklistFilterMapping struct {
	SourceField string `json:"sourceField"`
	RecordField string `json:"recordField"`
}

type runtimePicklistInfo struct {
	SourceObject   string                         `json:"sourceObject"`
	ValueField     string                         `json:"valueField"`
	LabelField     string                         `json:"labelField"`
	FilterMappings []runtimePicklistFilterMapping `json:"filterMappings"`
	SortField      string                         `json:"sortField,omitempty"`
	SortOrder      string                         `json:"sortOrder,omitempty"`
}

type FilteredLookupInfo struct {
	RuntimePicklist *runtimePicklistInfo `json:"runtimePicklist,omitempty"`
}

type schemaLookup interface {
	GetSchema(ctx context.Context, apiName string) *models.ObjectMetadata
}

func buildRuntimePicklistInfo(ctx context.Context, schemas schemaLookup, field models.FieldMetadata) *runtimePicklistInfo {
	if schemas == nil || field.Validator == nil {
		return nil
	}

	validator := strings.TrimSpace(*field.Validator)
	if !strings.EqualFold(validator, runtimeScopedPicklistValidator) {
		return nil
	}

	normalizedType := constants.NormalizeFieldType(string(field.Type))
	if normalizedType != constants.FieldTypePicklist && normalizedType != constants.FieldTypeMultiPicklist {
		return nil
	}

	if field.ControllingField == nil || len(field.ReferenceTo) != 1 {
		return nil
	}

	recordField := strings.TrimSpace(*field.ControllingField)
	sourceObject := strings.TrimSpace(field.ReferenceTo[0])
	if recordField == "" || sourceObject == "" {
		return nil
	}

	sourceSchema := schemas.GetSchema(ctx, sourceObject)
	if sourceSchema == nil {
		return nil
	}

	labelField := runtimePicklistLabelField(sourceSchema)
	if labelField == "" {
		return nil
	}

	sortField, sortOrder := runtimePicklistSort(sourceSchema, labelField)

	return &runtimePicklistInfo{
		SourceObject: sourceSchema.APIName,
		ValueField:   labelField,
		LabelField:   labelField,
		FilterMappings: []runtimePicklistFilterMapping{
			{
				SourceField: recordField,
				RecordField: recordField,
			},
		},
		SortField: sortField,
		SortOrder: sortOrder,
	}
}

func runtimePicklistLabelField(schema *models.ObjectMetadata) string {
	if schema == nil {
		return ""
	}

	for _, field := range schema.Fields {
		if strings.EqualFold(field.APIName, "Label") {
			return field.APIName
		}
	}

	for _, field := range schema.Fields {
		if field.IsNameField {
			return field.APIName
		}
	}

	for _, field := range schema.Fields {
		if strings.EqualFold(field.APIName, "Name") {
			return field.APIName
		}
	}

	return ""
}

func runtimePicklistSort(schema *models.ObjectMetadata, fallback string) (string, string) {
	if schema == nil {
		return fallback, "ASC"
	}

	for _, field := range schema.Fields {
		if strings.EqualFold(field.APIName, "SortOrder") {
			return field.APIName, "ASC"
		}
	}

	return fallback, "ASC"
}
