package mediagen

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 (always tried last) because:
//   - Daily quota limits (resets at midnight PT)
//   - Free tier was reduced ~92% in December 2025
//   - No way to check remaining quota before a request
//   - Terminus is ALWAYS tried regardless of cooldown
//
// The fallback strategy ensures requests succeed when possible.

// ProviderSet holds image providers for easy configuration.
type ProviderSet struct {
	LaoZhang ImageGenerator
	Gemini   ImageGenerator
}

// VideoProviderSet holds video providers for configuration.
type VideoProviderSet struct {
	LaoZhang VideoGenerator
	Gemini   VideoGenerator
}

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

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

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

// ProductionVideoConfig returns a video ManagerConfig for production workloads.
//
// Primary: LaoZhang (reliable pay-per-use)
// Terminus: Gemini (always tried as last resort)
func ProductionVideoConfig(providers VideoProviderSet, opts ...ConfigOption) ManagerConfig {
	videoProviders := []VideoGenerator{}

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

	cfg := ManagerConfig{
		VideoProviders: videoProviders,
		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
	}
}
