package elevenlabs

import (
	"errors"
	"fmt"

	"pitch-voiceover/pkg/httpkit"
)

// Sentinel errors for common error types.
// These are aliases for httpkit sentinels, so errors.Is works with either.
var (
	// ErrInvalidConfig indicates configuration validation failed
	ErrInvalidConfig = errors.New("elevenlabs: invalid configuration")

	// ErrQuotaExceeded indicates the API quota has been exceeded
	ErrQuotaExceeded = errors.New("elevenlabs: quota exceeded")

	// ErrVoiceNotFound indicates the requested voice does not exist
	ErrVoiceNotFound = errors.New("elevenlabs: voice not found")

	// ErrRateLimit indicates rate limit exceeded (HTTP 429)
	ErrRateLimit = httpkit.ErrRateLimit

	// ErrServerError indicates server-side error (HTTP 5xx)
	ErrServerError = httpkit.ErrServerError

	// ErrInvalidRequest indicates client error (HTTP 4xx except 429, 401)
	ErrInvalidRequest = httpkit.ErrBadRequest

	// ErrTimeout indicates request timeout
	ErrTimeout = httpkit.ErrTimeout

	// ErrUnauthorized indicates authentication failed (HTTP 401)
	ErrUnauthorized = httpkit.ErrUnauthorized
)

// APIError represents an error returned by the ElevenLabs API
type APIError struct {
	StatusCode int    // HTTP status code
	Message    string // Human-readable error message
	Status     string // Status from API response (e.g., "quota_exceeded")
	err        error  // Underlying error for wrapping
}

// Error implements the error interface
func (e *APIError) Error() string {
	if e.Status != "" {
		return fmt.Sprintf("elevenlabs api error (status %d): [%s] %s", e.StatusCode, e.Status, e.Message)
	}
	return fmt.Sprintf("elevenlabs api error (status %d): %s", e.StatusCode, e.Message)
}

// Unwrap implements the errors.Unwrap interface for error chains
func (e *APIError) Unwrap() error {
	return e.err
}

// NewAPIError creates a new APIError with the given parameters
func NewAPIError(statusCode int, message, status string, underlying error) *APIError {
	return &APIError{
		StatusCode: statusCode,
		Message:    message,
		Status:     status,
		err:        underlying,
	}
}

// IsRateLimitError checks if the error is a rate limit error
func IsRateLimitError(err error) bool {
	return errors.Is(err, ErrRateLimit)
}

// IsServerError checks if the error is a server error (5xx)
func IsServerError(err error) bool {
	return errors.Is(err, ErrServerError)
}

// IsRetryableError checks if the error should trigger a retry
func IsRetryableError(err error) bool {
	return httpkit.IsRetryable(err)
}

// IsUnauthorizedError checks if the error is an unauthorized error (401)
func IsUnauthorizedError(err error) bool {
	return errors.Is(err, ErrUnauthorized)
}

// IsTimeoutError checks if the error is a timeout error
func IsTimeoutError(err error) bool {
	return errors.Is(err, ErrTimeout)
}

// IsQuotaExceededError checks if the error is a quota exceeded error
func IsQuotaExceededError(err error) bool {
	return errors.Is(err, ErrQuotaExceeded)
}

// IsVoiceNotFoundError checks if the error is a voice not found error
func IsVoiceNotFoundError(err error) bool {
	return errors.Is(err, ErrVoiceNotFound)
}
