package persona

import "strings"

// SpeciesType defines the species of a character.
// This determines which validation rules apply.
type SpeciesType string

const (
	// SpeciesHuman represents a human character.
	// Validation includes ethnicity plausibility checks.
	SpeciesHuman SpeciesType = "human"

	// SpeciesHumanoid represents a humanoid/fantasy character.
	// Validation includes morphology consistency checks.
	SpeciesHumanoid SpeciesType = "humanoid"

	// SpeciesAndroid represents a synthetic/android character.
	// Minimal validation as features can be artificially constructed.
	SpeciesAndroid SpeciesType = "android"
)

// String returns the string representation.
func (s SpeciesType) String() string {
	return string(s)
}

// IsValid returns true if the species type is recognized.
func (s SpeciesType) IsValid() bool {
	switch s {
	case SpeciesHuman, SpeciesHumanoid, SpeciesAndroid:
		return true
	default:
		return false
	}
}

// ParseSpeciesType converts a string to SpeciesType.
// Returns SpeciesHuman for unrecognized values.
func ParseSpeciesType(s string) SpeciesType {
	switch strings.ToLower(strings.TrimSpace(s)) {
	case "human":
		return SpeciesHuman
	case "humanoid":
		return SpeciesHumanoid
	case "android":
		return SpeciesAndroid
	default:
		return SpeciesHuman
	}
}

// MorphLevel represents creature transformation intensity.
// Controls how much the subject deviates from human appearance.
type MorphLevel int

const (
	// MorphLevelHuman (0-24): Human with supernatural energy/expression.
	MorphLevelHuman MorphLevel = 0

	// MorphLevelSubtle (25-49): Subtle non-human features.
	// Pointed ears, unusual eye colors, small fangs, slightly elongated features.
	MorphLevelSubtle MorphLevel = 25

	// MorphLevelDemiHuman (50-74): Anime-style demi-human aesthetic.
	// Animal ears, tail, but human face and body. Catgirl/foxgirl territory.
	MorphLevelDemiHuman MorphLevel = 50

	// MorphLevelHybrid (75-99): Visible creature features.
	// Fur patterns, scale patches, claws, more pronounced non-human anatomy.
	MorphLevelHybrid MorphLevel = 75

	// MorphLevelCreature (100): Full anthropomorphic form.
	// Fully transformed while maintaining attractiveness and personality.
	MorphLevelCreature MorphLevel = 100
)

// Band returns the band name for a given morph level value.
func (m MorphLevel) Band() string {
	return MorphLevelBand(int(m))
}

// MorphLevelBand returns the band name for a given morph level value.
func MorphLevelBand(level int) string {
	switch {
	case level >= 100:
		return "creature"
	case level >= 75:
		return "hybrid"
	case level >= 50:
		return "demi_human"
	case level >= 25:
		return "subtle"
	default:
		return "human"
	}
}

// RequiresFeatures returns true if the morph level allows non-human features.
func MorphLevelRequiresFeatures(level int) bool {
	return level >= 25
}

// ParseMorphLevel parses a band name to its minimum MorphLevel value.
func ParseMorphLevel(band string) MorphLevel {
	switch strings.ToLower(strings.TrimSpace(band)) {
	case "creature":
		return MorphLevelCreature
	case "hybrid":
		return MorphLevelHybrid
	case "demi_human", "demihuman":
		return MorphLevelDemiHuman
	case "subtle":
		return MorphLevelSubtle
	default:
		return MorphLevelHuman
	}
}
