package persona

// IdentityDNA contains demographic and heritage information for a character.
// This is the foundational identity layer that influences all other DNA selections.
type IdentityDNA struct {
	// Ethnicity is the primary ethnic background used for feature distribution.
	Ethnicity EthnicityCode `json:"ethnicity" yaml:"ethnicity"`

	// Age in years (exact chronological age).
	Age int `json:"age" yaml:"age"`

	// Gender is the character's gender identity.
	Gender GenderIdentity `json:"gender" yaml:"gender"`

	// Nationality is the country/cultural background (e.g., "American", "Japanese").
	Nationality string `json:"nationality" yaml:"nationality"`

	// BirthCity is the city where the character was born.
	BirthCity string `json:"birth_city,omitempty" yaml:"birth_city,omitempty"`

	// CurrentCity is the city where the character currently resides.
	CurrentCity string `json:"current_city,omitempty" yaml:"current_city,omitempty"`

	// PrimaryHeritage is the dominant ethnic heritage (used for feature weighting).
	PrimaryHeritage EthnicityCode `json:"primary_heritage" yaml:"primary_heritage"`

	// SecondaryHeritage is the secondary ethnic heritage for mixed-race characters.
	// When set, MixPercentage determines the blend ratio.
	SecondaryHeritage *EthnicityCode `json:"secondary_heritage,omitempty" yaml:"secondary_heritage,omitempty"`

	// MixPercentage is the percentage of primary heritage (0-100).
	// E.g., 60 means 60% primary heritage, 40% secondary heritage.
	// Only relevant when SecondaryHeritage is set.
	MixPercentage int `json:"mix_percentage,omitempty" yaml:"mix_percentage,omitempty"`
}

// EthnicityCode represents standardized ethnicity categories.
// These map to feature distribution weights for face, hair, and eye selection.
type EthnicityCode string

const (
	EthnicityEastAsian      EthnicityCode = "east_asian"
	EthnicitySouthAsian     EthnicityCode = "south_asian"
	EthnicitySoutheastAsian EthnicityCode = "southeast_asian"
	EthnicityAfrican        EthnicityCode = "african"
	EthnicityHispanic       EthnicityCode = "hispanic"
	EthnicityMiddleEastern  EthnicityCode = "middle_eastern"
	EthnicityCaucasian      EthnicityCode = "caucasian"
	EthnicityMixed          EthnicityCode = "mixed"
)

// String returns the string representation.
func (e EthnicityCode) String() string {
	return string(e)
}

// IsValid returns true if the ethnicity code is recognized.
func (e EthnicityCode) IsValid() bool {
	switch e {
	case EthnicityEastAsian, EthnicitySouthAsian, EthnicitySoutheastAsian,
		EthnicityAfrican, EthnicityHispanic, EthnicityMiddleEastern,
		EthnicityCaucasian, EthnicityMixed:
		return true
	default:
		return false
	}
}

// AllEthnicities returns all valid ethnicity codes.
func AllEthnicities() []EthnicityCode {
	return []EthnicityCode{
		EthnicityEastAsian,
		EthnicitySouthAsian,
		EthnicitySoutheastAsian,
		EthnicityAfrican,
		EthnicityHispanic,
		EthnicityMiddleEastern,
		EthnicityCaucasian,
		EthnicityMixed,
	}
}

// GenderIdentity represents the character's gender.
type GenderIdentity string

const (
	GenderWoman     GenderIdentity = "woman"
	GenderMan       GenderIdentity = "man"
	GenderNonBinary GenderIdentity = "non_binary"
)

// String returns the string representation.
func (g GenderIdentity) String() string {
	return string(g)
}

// IsValid returns true if the gender identity is recognized.
func (g GenderIdentity) IsValid() bool {
	switch g {
	case GenderWoman, GenderMan, GenderNonBinary:
		return true
	default:
		return false
	}
}

// AllGenders returns all valid gender identities.
func AllGenders() []GenderIdentity {
	return []GenderIdentity{
		GenderWoman,
		GenderMan,
		GenderNonBinary,
	}
}
