package skills

import (
	"strings"
)

type ActivationResult struct {
	Active  bool
	Reason  string
	Skill   *Skill
}

func CheckActivation(skill *Skill, availableTools []string) ActivationResult {
	if len(skill.RequiresTools) == 0 && len(skill.FallbackForTools) == 0 {
		return ActivationResult{
			Active: true,
			Reason: "no activation conditions",
			Skill:  skill,
		}
	}

	toolSet := make(map[string]bool, len(availableTools))
	for _, t := range availableTools {
		toolSet[strings.ToLower(t)] = true
	}

	if len(skill.RequiresTools) > 0 {
		for _, req := range skill.RequiresTools {
			if !toolSet[strings.ToLower(req)] {
				return ActivationResult{
					Active: false,
					Reason: "missing required tool: " + req,
					Skill:  skill,
				}
			}
		}
		return ActivationResult{
			Active: true,
			Reason: "all required tools available",
			Skill:  skill,
		}
	}

	if len(skill.FallbackForTools) > 0 {
		allPresent := true
		for _, fb := range skill.FallbackForTools {
			if !toolSet[strings.ToLower(fb)] {
				allPresent = false
				break
			}
		}
		if allPresent {
			return ActivationResult{
				Active: false,
				Reason: "primary tools available, fallback not needed",
				Skill:  skill,
			}
		}
		return ActivationResult{
			Active: true,
			Reason: "primary tools absent, activating as fallback",
			Skill:  skill,
		}
	}

	return ActivationResult{Active: true, Skill: skill}
}

func FilterActiveSkills(skillsList []Skill, availableTools []string) []Skill {
	var active []Skill
	for i := range skillsList {
		result := CheckActivation(&skillsList[i], availableTools)
		if result.Active {
			active = append(active, skillsList[i])
		}
	}
	return active
}

func GroupByReadiness(skillsList []Skill, availableTools []string) (available, needsSetup, unsupported []Skill) {
	toolSet := make(map[string]bool, len(availableTools))
	for _, t := range availableTools {
		toolSet[strings.ToLower(t)] = true
	}

	for i := range skillsList {
		s := &skillsList[i]
		if len(s.RequiresTools) == 0 && len(s.FallbackForTools) == 0 {
			missing := CheckDependencies(s)
			if len(missing) == 0 {
				available = append(available, *s)
			} else {
				needsSetup = append(needsSetup, *s)
			}
			continue
		}

		allReqMet := true
		for _, req := range s.RequiresTools {
			if !toolSet[strings.ToLower(req)] {
				allReqMet = false
				break
			}
		}
		if allReqMet && len(s.RequiresTools) > 0 {
			available = append(available, *s)
		} else if !allReqMet && len(s.RequiresTools) > 0 {
			unsupported = append(unsupported, *s)
		}

		if len(s.FallbackForTools) > 0 {
			anyMissing := false
			for _, fb := range s.FallbackForTools {
				if !toolSet[strings.ToLower(fb)] {
					anyMissing = true
					break
				}
			}
			if anyMissing {
				available = append(available, *s)
			}
		}
	}
	return
}
