package models

import (
	"encoding/json"
	"fmt"
	"strings"
)

// LookupScopeConfig declares metadata-owned lookup search scoping for a
// referencing field. The substrate stores this in FieldMetadata.ValidatorConfig
// when Validator is set to runtime_scoped_lookup.
type LookupScopeConfig struct {
	FilterMappings []LookupScopeFilterMapping `json:"filterMappings,omitempty"`
}

type LookupScopeFilterMapping struct {
	RecordField string `json:"recordField"`
	SourceField string `json:"sourceField"`
	TargetField string `json:"targetField"`
}

func ParseLookupScopeConfig(raw *string) (*LookupScopeConfig, error) {
	if raw == nil || strings.TrimSpace(*raw) == "" {
		return nil, fmt.Errorf("lookup scope config is empty")
	}

	var cfg LookupScopeConfig
	if err := json.Unmarshal([]byte(*raw), &cfg); err != nil {
		return nil, fmt.Errorf("parse lookup scope config: %w", err)
	}
	if err := cfg.Validate(); err != nil {
		return nil, err
	}
	return &cfg, nil
}

func (c *LookupScopeConfig) Validate() error {
	if c == nil {
		return fmt.Errorf("lookup scope config is nil")
	}
	if len(c.FilterMappings) == 0 {
		return fmt.Errorf("lookup scope config requires at least one filter mapping")
	}
	for i, mapping := range c.FilterMappings {
		if strings.TrimSpace(mapping.RecordField) == "" {
			return fmt.Errorf("lookup scope mapping %d missing recordField", i)
		}
		if strings.TrimSpace(mapping.SourceField) == "" {
			return fmt.Errorf("lookup scope mapping %d missing sourceField", i)
		}
		if strings.TrimSpace(mapping.TargetField) == "" {
			return fmt.Errorf("lookup scope mapping %d missing targetField", i)
		}
	}
	return nil
}
