package validator

import (
	"baron-sso-backend/internal/domain"
	"fmt"
	"reflect"
	"strings"
)

// ValidateIDPCompatibility checks if the provided IDP supports all required fields defined in the BrokerUser model.
func ValidateIDPCompatibility(brokerModel interface{}, idp domain.IdentityProvider) error {
	metadata, err := idp.GetMetadata()
	if err != nil {
		return fmt.Errorf("failed to fetch metadata from IDP %s: %w", idp.Name(), err)
	}

	supportedMap := make(map[string]bool)
	for _, f := range metadata.SupportedFields {
		supportedMap[f] = true
	}

	t := reflect.TypeOf(brokerModel)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		// Check "required" tag
		isRequired := field.Tag.Get("required") == "true"
		jsonTag := field.Tag.Get("json")
		fieldName := strings.Split(jsonTag, ",")[0]

		// Skip if fieldName is empty or if it's the Attributes map (handled separately)
		if fieldName == "" {
			continue
		}

		if fieldName != "attributes" {
			if isRequired && !supportedMap[fieldName] {
				return fmt.Errorf("IDP %s does not support required field: %s", idp.Name(), fieldName)
			}
		}

		// Check "required_keys" tag for map types (Custom Attributes)
		if fieldName == "attributes" {
			reqKeys := field.Tag.Get("required_keys")
			if reqKeys != "" {
				keys := strings.Split(reqKeys, ",")
				for _, key := range keys {
					key = strings.TrimSpace(key)
					if !supportedMap[key] {
						return fmt.Errorf("IDP %s does not support required custom attribute: %s", idp.Name(), key)
					}
				}
			}
		}
	}

	return nil
}
