package ux

import (
	"fmt"
	"strings"
)

// ErrorType represents different categories of errors
type ErrorType string

const (
	ErrorTypeConfig        ErrorType = "configuration"
	ErrorTypePackage       ErrorType = "package_management"
	ErrorTypeContainer     ErrorType = "container"
	ErrorTypeManifest      ErrorType = "manifest_generation"
	ErrorTypeFilesystem    ErrorType = "filesystem"
	ErrorTypeNetwork       ErrorType = "network"
	ErrorTypePermission    ErrorType = "permission"
	ErrorTypeValidation    ErrorType = "validation"
	ErrorTypeDependency    ErrorType = "dependency"
	ErrorTypeBuild         ErrorType = "build"
)

// UserError represents a user-friendly error with context and suggestions
type UserError struct {
	Type        ErrorType
	Message     string
	Context     string
	Suggestion  string
	OriginalErr error
	HelpURL     string
}

func (e *UserError) Error() string {
	return e.Message
}

// NewUserError creates a new user-friendly error
func NewUserError(errType ErrorType, message, context, suggestion string, originalErr error) *UserError {
	return &UserError{
		Type:        errType,
		Message:     message,
		Context:     context,
		Suggestion:  suggestion,
		OriginalErr: originalErr,
	}
}

// WithHelpURL adds a help URL to the error
func (e *UserError) WithHelpURL(url string) *UserError {
	e.HelpURL = url
	return e
}

// FormatError formats an error for user display
func FormatError(err error) string {
	if userErr, ok := err.(*UserError); ok {
		return formatUserError(userErr)
	}
	return formatGenericError(err)
}

func formatUserError(err *UserError) string {
	var sb strings.Builder
	
	sb.WriteString(fmt.Sprintf("❌ %s Error: %s\n", strings.Title(string(err.Type)), err.Message))
	
	if err.Context != "" {
		sb.WriteString(fmt.Sprintf("   Context: %s\n", err.Context))
	}
	
	if err.Suggestion != "" {
		sb.WriteString(fmt.Sprintf("   💡 Suggestion: %s\n", err.Suggestion))
	}
	
	if err.HelpURL != "" {
		sb.WriteString(fmt.Sprintf("   📖 Help: %s\n", err.HelpURL))
	}
	
	if err.OriginalErr != nil {
		sb.WriteString(fmt.Sprintf("   🔍 Technical details: %v\n", err.OriginalErr))
	}
	
	return sb.String()
}

func formatGenericError(err error) string {
	return fmt.Sprintf("❌ Error: %v\n", err)
}

// Common error constructors for Debian-specific issues

// ConfigError creates a configuration-related error
func ConfigError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeConfig,
		message,
		"Configuration file or settings issue",
		"Check your .config/registry.yaml file and ensure all required fields are present",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/configuration")
}

// PackageError creates a package management error
func PackageError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypePackage,
		message,
		"APT package resolution or installation issue",
		"Ensure your system has apt-cache available and repositories are properly configured",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/package-management")
}

// ContainerError creates a container-related error
func ContainerError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeContainer,
		message,
		"Container image or runtime issue",
		"Ensure the container image exists and podman/docker is properly configured",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/containers")
}

// ManifestError creates a manifest generation error
func ManifestError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeManifest,
		message,
		"OSBuild manifest generation issue",
		"Check your package definitions and ensure all required packages are available",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/manifest-generation")
}

// FilesystemError creates a filesystem-related error
func FilesystemError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeFilesystem,
		message,
		"Filesystem or disk operation issue",
		"Check available disk space and filesystem permissions",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/filesystem")
}

// PermissionError creates a permission-related error
func PermissionError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypePermission,
		message,
		"Insufficient permissions for operation",
		"Run with appropriate permissions or check file/directory ownership",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/permissions")
}

// ValidationError creates a validation error
func ValidationError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeValidation,
		message,
		"Input validation failed",
		"Check your command line arguments and configuration values",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/validation")
}

// DependencyError creates a dependency error
func DependencyError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeDependency,
		message,
		"Missing or incompatible dependency",
		"Install required dependencies or check version compatibility",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/dependencies")
}

// BuildError creates a build process error
func BuildError(message string, originalErr error) *UserError {
	return NewUserError(
		ErrorTypeBuild,
		message,
		"Image build process failed",
		"Check build logs and ensure all prerequisites are met",
		originalErr,
	).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/build-process")
}
