package mediagen

import (
	"errors"
	"fmt"

	"{{GO_MODULE}}/pkg/routing"
)

// Domain errors for programmatic error handling with errors.Is().
//
// IMPORTANT: Core routing errors (ErrRateLimit, ErrQuotaExceeded, ErrServerUnavailable)
// are defined in pkg/routing. Provider implementations should wrap those errors.
var (
	// ErrInvalidConfig indicates invalid configuration.
	ErrInvalidConfig = errors.New("invalid configuration")

	// ErrInvalidRequest indicates invalid request parameters.
	ErrInvalidRequest = errors.New("invalid request")

	// ErrNoProvidersConfigured indicates no providers were configured.
	ErrNoProvidersConfigured = errors.New("no providers configured")

	// ErrAllProvidersFailed indicates all providers failed (fallback strategy).
	// This is an alias for routing.ErrAllProvidersFailed.
	ErrAllProvidersFailed = routing.ErrAllProvidersFailed

	// ErrProviderUnavailable indicates a provider is unavailable.
	ErrProviderUnavailable = errors.New("provider unavailable")

	// ErrRateLimit indicates provider returned a rate limit (429) error.
	// Re-exported from routing for convenience.
	ErrRateLimit = routing.ErrRateLimit

	// ErrQuotaExceeded indicates provider's quota has been exhausted.
	// Re-exported from routing for convenience.
	ErrQuotaExceeded = routing.ErrQuotaExceeded

	// ErrServerUnavailable indicates a transient server error (5xx).
	// Re-exported from routing for convenience.
	ErrServerUnavailable = routing.ErrServerUnavailable
)

// ProviderLaoZhang is the provider name for LaoZhang (pay-per-use, never rate limited).
const ProviderLaoZhang = "laozhang"

// ProviderError wraps provider-specific errors with additional context.
type ProviderError struct {
	Provider string // Provider name
	Op       string // Operation ("GenerateImage", "GenerateVideo", "Health")
	Err      error  // Underlying error
}

func (e *ProviderError) Error() string {
	return fmt.Sprintf("%s: %s: %v", e.Provider, e.Op, e.Err)
}

func (e *ProviderError) Unwrap() error {
	return e.Err
}

// NewProviderError creates a new ProviderError.
func NewProviderError(provider, op string, err error) error {
	return &ProviderError{
		Provider: provider,
		Op:       op,
		Err:      err,
	}
}
