package records

import (
	"context"
	"database/sql/driver"
	"strings"

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

type runtimeScopedLookupMetaRepo struct {
	stubUpsertMetaRepo
	schemas map[string]*models.ObjectMetadata
}

func (r *runtimeScopedLookupMetaRepo) GetAllSchemas(ctx context.Context) ([]*models.ObjectMetadata, error) {
	out := make([]*models.ObjectMetadata, 0, len(r.schemas))
	for _, schema := range r.schemas {
		out = append(out, schema)
	}
	return out, nil
}

func (r *runtimeScopedLookupMetaRepo) GetSchemaByAPIName(ctx context.Context, apiName string) (*models.ObjectMetadata, error) {
	for name, schema := range r.schemas {
		if strings.EqualFold(name, apiName) || strings.EqualFold(schema.APIName, apiName) {
			return schema, nil
		}
	}
	return nil, nil
}

func runtimeScopedLookupSchemas() (*models.ObjectMetadata, *models.ObjectMetadata, *models.ObjectMetadata) {
	validator := runtimeScopedLookupValidatorName
	config := `{"filterMappings":[{"recordField":"OpportunityId","sourceField":"Pricebook2Id","targetField":"Pricebook2Id"}]}`
	lineItemSchema := &models.ObjectMetadata{
		APIName: "OpportunityLineItem",
		Fields: []models.FieldMetadata{
			{
				APIName:         "PricebookEntryId",
				Type:            constants.FieldTypeReference,
				ReferenceTo:     []string{"PricebookEntry"},
				Validator:       &validator,
				ValidatorConfig: &config,
			},
			{
				APIName:     "OpportunityId",
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{"Opportunity"},
			},
		},
	}
	opportunitySchema := &models.ObjectMetadata{
		APIName: "Opportunity",
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, Type: constants.FieldTypeString},
			{APIName: "Pricebook2Id", Type: constants.FieldTypeReference},
		},
	}
	pricebookEntrySchema := &models.ObjectMetadata{
		APIName: "PricebookEntry",
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, Type: constants.FieldTypeString},
			{APIName: "Pricebook2Id", Type: constants.FieldTypeReference},
		},
	}
	return lineItemSchema, opportunitySchema, pricebookEntrySchema
}

func toDriverValues(values []interface{}) []driver.Value {
	out := make([]driver.Value, 0, len(values))
	for _, value := range values {
		out = append(out, value)
	}
	return out
}
