package persona

import "fmt"

// ValidateHumanoidMorphology validates morphology features for humanoid characters.
// Returns errors if morphology features are present without sufficient MorphLevel.
func ValidateHumanoidMorphology(c *Character) ValidationErrors {
	var errs ValidationErrors

	if c == nil || c.Species != SpeciesHumanoid {
		return errs
	}

	morphology := c.Morphology
	if morphology == nil || !morphology.HasFeatures() {
		return errs // No morphology features, nothing to validate
	}

	// Check if morph level allows features
	if c.MorphLevel < 25 {
		errs.Add("morph_level",
			fmt.Sprintf("morph level %d is too low for morphology features (requires >= 25)", c.MorphLevel),
			ErrMorphLevelRequired)
		return errs
	}

	// Validate individual feature types
	if morphology.EarType != "" && !IsValidEarType(morphology.EarType) {
		errs.AddValue("morphology.ear_type", morphology.EarType,
			fmt.Sprintf("invalid ear type: %s", morphology.EarType), ErrInvalidFeatureType)
	}

	if morphology.TailType != "" && !IsValidTailType(morphology.TailType) {
		errs.AddValue("morphology.tail_type", morphology.TailType,
			fmt.Sprintf("invalid tail type: %s", morphology.TailType), ErrInvalidFeatureType)
	}

	if morphology.FangType != "" && !IsValidFangType(morphology.FangType) {
		errs.AddValue("morphology.fang_type", morphology.FangType,
			fmt.Sprintf("invalid fang type: %s", morphology.FangType), ErrInvalidFeatureType)
	}

	if morphology.WingType != "" && !IsValidWingType(morphology.WingType) {
		errs.AddValue("morphology.wing_type", morphology.WingType,
			fmt.Sprintf("invalid wing type: %s", morphology.WingType), ErrInvalidFeatureType)
	}

	if morphology.HornType != "" && !IsValidHornType(morphology.HornType) {
		errs.AddValue("morphology.horn_type", morphology.HornType,
			fmt.Sprintf("invalid horn type: %s", morphology.HornType), ErrInvalidFeatureType)
	}

	if morphology.ClawType != "" && !IsValidClawType(morphology.ClawType) {
		errs.AddValue("morphology.claw_type", morphology.ClawType,
			fmt.Sprintf("invalid claw type: %s", morphology.ClawType), ErrInvalidFeatureType)
	}

	// Validate morph level vs feature intensity
	if err := validateMorphLevelFeatureConsistency(c.MorphLevel, morphology); err != nil {
		errs.Add("morphology", err.Error(), ErrInconsistentAttributes)
	}

	return errs
}

// validateMorphLevelFeatureConsistency ensures features match the morph level band.
func validateMorphLevelFeatureConsistency(morphLevel int, m *MorphologyHints) error {
	if m == nil {
		return nil
	}

	band := MorphLevelBand(morphLevel)

	// Count features
	featureCount := 0
	hasExtremeFeatures := false

	if m.EarType != "" {
		featureCount++
	}
	if m.TailType != "" {
		featureCount++
	}
	if m.FangType != "" {
		featureCount++
	}
	if m.WingType != "" {
		featureCount++
		hasExtremeFeatures = true // Wings are extreme
	}
	if m.HornType != "" {
		featureCount++
		if m.HornType == "demon" || m.HornType == "antlers" {
			hasExtremeFeatures = true
		}
	}
	if m.ClawType != "" {
		featureCount++
		if m.ClawType == "talons" || m.ClawType == "prominent" {
			hasExtremeFeatures = true
		}
	}
	if len(m.FurPatterns) > 0 {
		featureCount++
		if len(m.FurPatterns) > 2 {
			hasExtremeFeatures = true
		}
	}
	if m.ScalePattern != "" {
		featureCount++
		hasExtremeFeatures = true // Scales are extreme
	}

	// Validate based on band
	switch band {
	case "subtle":
		// At subtle level (25-49), only minor features allowed
		if hasExtremeFeatures {
			return fmt.Errorf("extreme features (wings, scales, heavy fur) require morph level >= 75")
		}
		if featureCount > 3 {
			return fmt.Errorf("too many features (%d) for subtle morph level (max 3)", featureCount)
		}

	case "demi_human":
		// At demi-human level (50-74), moderate features allowed
		if hasExtremeFeatures {
			return fmt.Errorf("extreme features (wings, scales, heavy fur) require morph level >= 75")
		}

	case "hybrid", "creature":
		// At hybrid (75-99) and creature (100), all features allowed
		// No restrictions
	}

	return nil
}

// RecommendMorphLevel recommends a minimum morph level for given morphology.
func RecommendMorphLevel(m *MorphologyHints) int {
	if m == nil || !m.HasFeatures() {
		return 0
	}

	// Check for extreme features
	hasExtreme := m.WingType != "" ||
		m.ScalePattern != "" ||
		m.ClawType == "talons" ||
		m.ClawType == "prominent" ||
		m.HornType == "demon" ||
		m.HornType == "antlers" ||
		len(m.FurPatterns) > 2

	if hasExtreme {
		return 75 // Hybrid level
	}

	// Check for moderate features
	featureCount := 0
	if m.EarType != "" {
		featureCount++
	}
	if m.TailType != "" {
		featureCount++
	}
	if m.FangType != "" {
		featureCount++
	}
	if m.HornType != "" {
		featureCount++
	}
	if m.ClawType != "" {
		featureCount++
	}
	if len(m.FurPatterns) > 0 {
		featureCount++
	}

	if featureCount > 3 {
		return 50 // Demi-human level
	}

	return 25 // Subtle level
}
