package textgen

import "log/slog"

// Provider Ordering Strategy
//
// Production ordering: LaoZhang (primary) -> Gemini (terminus)
//
// LaoZhang is primary because:
//   - Pay-per-use pricing, no hard daily limits
//   - More predictable availability for production traffic
//   - Gemini's unpredictable quota exhaustion would frustrate users
//   - Cost is acceptable for revenue-generating features
//
// Gemini is terminus because:
//   - Daily quota limits (resets at midnight PT)
//   - Free tier was reduced ~92% in December 2025
//   - Terminus is ALWAYS tried regardless of cooldown
//
// The fallback strategy ensures requests succeed when possible.

// ProviderSet holds text providers for easy configuration.
type ProviderSet struct {
	LaoZhang TextGenerator
	Gemini   TextGenerator
}

// ProductionConfig returns a ManagerConfig optimized for production workloads.
//
// Primary: LaoZhang (reliable pay-per-use)
// Terminus: Gemini (may fail on quota, but always tried as last resort)
//
// Use this for:
//   - User-initiated text generation
//   - Production API endpoints
//   - Any feature where reliability matters more than cost
func ProductionConfig(providers ProviderSet, opts ...ConfigOption) ManagerConfig {
	textProviders := []TextGenerator{}

	// Build provider list in order: LaoZhang -> Gemini (terminus)
	if providers.LaoZhang != nil {
		textProviders = append(textProviders, providers.LaoZhang)
	}
	if providers.Gemini != nil {
		textProviders = append(textProviders, providers.Gemini)
	}

	cfg := ManagerConfig{
		Providers: textProviders,
		Strategy:  StrategyFallback,
	}
	for _, opt := range opts {
		opt(&cfg)
	}
	return cfg
}

// ConfigOption allows customizing preset configurations.
type ConfigOption func(*ManagerConfig)

// WithLogger sets a custom logger.
func WithLogger(logger *slog.Logger) ConfigOption {
	return func(cfg *ManagerConfig) {
		cfg.Logger = logger
	}
}

// WithMetrics sets a metrics hook for observability.
func WithMetrics(hook MetricsHook) ConfigOption {
	return func(cfg *ManagerConfig) {
		cfg.OnMetrics = hook
	}
}

// WithStrategy overrides the default fallback strategy.
// Use sparingly - the presets use StrategyFallback for a reason.
func WithStrategy(strategy Strategy) ConfigOption {
	return func(cfg *ManagerConfig) {
		cfg.Strategy = strategy
	}
}
