package model

import (
	"github.com/tech/sendico/pkg/discovery"
	"strings"
)

var supportedRails = map[Rail]struct{}{
	discovery.RailCrypto:             {},
	discovery.RailProviderSettlement: {},
	discovery.RailLedger:             {},
	discovery.RailCardPayout:         {},
	discovery.RailFiatOnRamp:         {},
	discovery.RailFiatOffRamp:        {},
}

// ParseRail canonicalizes string values into a Rail token.
func ParseRail(value string) Rail {
	clean := strings.ToUpper(strings.TrimSpace(value))
	if clean == "" {
		return discovery.RailUnspecified
	}
	clean = strings.ReplaceAll(clean, "-", "_")
	clean = strings.ReplaceAll(clean, " ", "_")
	for strings.Contains(clean, "__") {
		clean = strings.ReplaceAll(clean, "__", "_")
	}

	switch clean {
	case string(discovery.RailCrypto), "RAIL_CRYPTO":
		return discovery.RailCrypto
	case string(discovery.RailProviderSettlement), "PROVIDER_SETTLEMENT", "RAIL_SETTLEMENT", "RAIL_PROVIDER_SETTLEMENT":
		return discovery.RailProviderSettlement
	case string(discovery.RailLedger), "RAIL_LEDGER":
		return discovery.RailLedger
	case string(discovery.RailCardPayout), "CARD_PAYOUT", "RAIL_CARD", "RAIL_CARD_PAYOUT":
		return discovery.RailCardPayout
	case string(discovery.RailFiatOnRamp), "FIAT_ONRAMP", "RAIL_ONRAMP", "RAIL_FIAT_ONRAMP":
		return discovery.RailFiatOnRamp
	case string(discovery.RailFiatOffRamp), "FIAT_OFFRAMP", "RAIL_OFFRAMP", "RAIL_FIAT_OFFRAMP":
		return discovery.RailFiatOffRamp
	default:
		return discovery.RailUnspecified
	}
}

// IsSupportedRail reports whether rail is recognized by payment planning.
func IsSupportedRail(rail Rail) bool {
	_, ok := supportedRails[ParseRail(string(rail))]
	return ok
}

func normalizeRail(value Rail) Rail {
	parsed := ParseRail(string(value))
	if parsed != discovery.RailUnspecified {
		return parsed
	}

	clean := strings.ToUpper(strings.TrimSpace(string(value)))
	if clean == "" {
		return discovery.RailUnspecified
	}

	return Rail(clean)
}
