package client_test

import (
	"context"
	"fmt"

	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/maplefile/client"
)

// Example of handling RFC 9457 errors with validation details
func ExampleAPIError_validation() {
	c := client.NewLocal()

	// Attempt to register with invalid data
	_, err := c.Register(context.Background(), &client.RegisterInput{
		Email:     "", // Missing required field
		FirstName: "", // Missing required field
		// ... other fields
	})

	if err != nil {
		// Check if it's an API error
		if apiErr, ok := err.(*client.APIError); ok {
			fmt.Printf("Error Type: %s\n", apiErr.Type)
			fmt.Printf("Status: %d\n", apiErr.Status)
			fmt.Printf("Title: %s\n", apiErr.Title)

			// Check for validation errors
			if client.IsValidationError(err) {
				fmt.Println("\nValidation Errors:")
				for field, message := range apiErr.GetValidationErrors() {
					fmt.Printf("  %s: %s\n", field, message)
				}

				// Check for specific field error
				if apiErr.HasFieldError("email") {
					fmt.Printf("\nEmail error: %s\n", apiErr.GetFieldError("email"))
				}
			}
		}
	}
}

// Example of checking specific error types
func ExampleAPIError_statusChecks() {
	c := client.NewProduction()

	user, err := c.GetMe(context.Background())
	if err != nil {
		// Use helper functions to check error types
		switch {
		case client.IsUnauthorized(err):
			fmt.Println("Authentication required - please login")
			// Redirect to login

		case client.IsNotFound(err):
			fmt.Println("User not found")
			// Handle not found

		case client.IsForbidden(err):
			fmt.Println("Access denied")
			// Show permission error

		case client.IsTooManyRequests(err):
			fmt.Println("Rate limit exceeded - please try again later")
			// Implement backoff

		case client.IsValidationError(err):
			fmt.Println("Validation failed - please check your input")
			// Show validation errors

		default:
			fmt.Printf("Unexpected error: %v\n", err)
		}
		return
	}

	fmt.Printf("Welcome, %s!\n", user.Name)
}

// Example of extracting error details for logging
func ExampleAPIError_logging() {
	c := client.NewProduction()

	_, err := c.CreateCollection(context.Background(), &client.CreateCollectionInput{
		Name: "Test Collection",
	})

	if err != nil {
		if apiErr, ok := err.(*client.APIError); ok {
			// Log structured error details
			fmt.Printf("API Error Details:\n")
			fmt.Printf("  Type: %s\n", apiErr.Type)
			fmt.Printf("  Status: %d\n", apiErr.StatusCode())
			fmt.Printf("  Title: %s\n", apiErr.Title)
			fmt.Printf("  Detail: %s\n", apiErr.Detail)
			fmt.Printf("  Instance: %s\n", apiErr.Instance)
			fmt.Printf("  TraceID: %s\n", apiErr.TraceID)
			fmt.Printf("  Timestamp: %s\n", apiErr.Timestamp)

			if len(apiErr.Errors) > 0 {
				fmt.Println("  Field Errors:")
				for field, msg := range apiErr.Errors {
					fmt.Printf("    %s: %s\n", field, msg)
				}
			}
		}
	}
}

// Example of handling errors in a form validation context
func ExampleAPIError_formValidation() {
	c := client.NewLocal()

	type FormData struct {
		Email     string
		FirstName string
		LastName  string
		Password  string
	}

	form := FormData{
		Email:     "invalid-email",
		FirstName: "",
		LastName:  "Doe",
		Password:  "weak",
	}

	_, err := c.Register(context.Background(), &client.RegisterInput{
		Email:     form.Email,
		FirstName: form.FirstName,
		LastName:  form.LastName,
		// ... other fields
	})

	if err != nil {
		if apiErr, ok := err.(*client.APIError); ok {
			// Build form error messages
			formErrors := make(map[string]string)

			if apiErr.HasFieldError("email") {
				formErrors["email"] = apiErr.GetFieldError("email")
			}
			if apiErr.HasFieldError("first_name") {
				formErrors["first_name"] = apiErr.GetFieldError("first_name")
			}
			if apiErr.HasFieldError("last_name") {
				formErrors["last_name"] = apiErr.GetFieldError("last_name")
			}

			// Display errors to user
			for field, msg := range formErrors {
				fmt.Printf("Form field '%s': %s\n", field, msg)
			}
		}
	}
}

// Example of handling conflict errors
func ExampleAPIError_conflict() {
	c := client.NewProduction()

	_, err := c.Register(context.Background(), &client.RegisterInput{
		Email: "existing@example.com",
		// ... other fields
	})

	if err != nil {
		if client.IsConflict(err) {
			if apiErr, ok := err.(*client.APIError); ok {
				// The Detail field contains the conflict explanation
				fmt.Printf("Registration failed: %s\n", apiErr.Detail)
				// Output: "Registration failed: User with this email already exists"
			}
		}
	}
}
