// Package avatar provides pure types and URL builders for avatar image providers.
// No I/O — only data transformations.
package avatar

import (
	"fmt"
	"net/url"
)

// Provider identifies an avatar generation service.
type Provider string

const (
	// ProviderDiceBear generates illustrated avatars via DiceBear API.
	// Styles: adventurer, avataaars, bottts, fun-emoji, identicon, initials,
	// lorelei, micah, miniavs, notionists, open-peeps, personas, pixel-art, shapes, thumbs.
	ProviderDiceBear Provider = "dicebear"

	// ProviderRoboHash generates robot/monster/head images from any text.
	// Sets: set1 (robots), set2 (monsters), set3 (heads), set4 (cats), set5 (humans).
	ProviderRoboHash Provider = "robohash"

	// ProviderMultiavatar generates unique multicultural avatars from a string.
	ProviderMultiavatar Provider = "multiavatar"
)

// DiceBearStyle is a style option for the DiceBear provider.
type DiceBearStyle string

const (
	DiceBearBottts    DiceBearStyle = "bottts"
	DiceBearPixelArt  DiceBearStyle = "pixel-art"
	DiceBearAdventurer DiceBearStyle = "adventurer"
	DiceBearShapes    DiceBearStyle = "shapes"
	DiceBearFunEmoji  DiceBearStyle = "fun-emoji"
	DiceBearIdenticon DiceBearStyle = "identicon"
	DiceBearThumbs    DiceBearStyle = "thumbs"
)

// RoboHashSet is a set option for the RoboHash provider.
type RoboHashSet string

const (
	RoboHashRobots   RoboHashSet = "set1"
	RoboHashMonsters RoboHashSet = "set2"
	RoboHashHeads    RoboHashSet = "set3"
	RoboHashCats     RoboHashSet = "set4"
	RoboHashHumans   RoboHashSet = "set5"
)

// Options configures avatar generation.
type Options struct {
	// Size in pixels (square). Default: 256.
	Size int

	// DiceBear-specific style. Default: bottts.
	DiceBearStyle DiceBearStyle

	// RoboHash-specific set. Default: set1 (robots).
	RoboHashSet RoboHashSet
}

// DefaultOptions returns sensible defaults for bot avatars.
func DefaultOptions() Options {
	return Options{
		Size:          256,
		DiceBearStyle: DiceBearBottts,
		RoboHashSet:   RoboHashRobots,
	}
}

// URL returns the avatar image URL for the given provider and seed (typically the agent name/ID).
// Pure function — no I/O.
func URL(provider Provider, seed string, opts Options) string {
	if opts.Size <= 0 {
		opts.Size = 256
	}
	encoded := url.PathEscape(seed)

	switch provider {
	case ProviderDiceBear:
		style := opts.DiceBearStyle
		if style == "" {
			style = DiceBearBottts
		}
		return fmt.Sprintf("https://api.dicebear.com/9.x/%s/png?seed=%s&size=%d",
			style, url.QueryEscape(seed), opts.Size)

	case ProviderRoboHash:
		set := opts.RoboHashSet
		if set == "" {
			set = RoboHashRobots
		}
		return fmt.Sprintf("https://robohash.org/%s.png?set=%s&size=%dx%d",
			encoded, set, opts.Size, opts.Size)

	case ProviderMultiavatar:
		return fmt.Sprintf("https://api.multiavatar.com/%s.png?apikey=Wookie",
			encoded)

	default:
		return URL(ProviderDiceBear, seed, opts)
	}
}

// AllProviders returns the list of supported providers.
func AllProviders() []Provider {
	return []Provider{ProviderDiceBear, ProviderRoboHash, ProviderMultiavatar}
}
