// Package loot provides a declarative, rule-based loot filter engine.
//
// Loot rules are defined in YAML and evaluated against detected items.
// Supports complex matching on type, name, rarity, properties, and more.
package loot

import (
	"strings"

	"git.cloonar.com/openclawd/iso-bot/pkg/plugin"
)

// Priority levels for pickup ordering.
const (
	PriorityLow    = 1
	PriorityNormal = 5
	PriorityHigh   = 8
	PriorityCritical = 10
)

// Condition defines a match condition for a loot rule.
type Condition struct {
	Type         *string  `yaml:"type,omitempty"`          // "unique", "set", "rare", etc.
	NameContains *string  `yaml:"name_contains,omitempty"` // substring match
	NameExact    *string  `yaml:"name_exact,omitempty"`    // exact match
	MinRarity    *int     `yaml:"min_rarity,omitempty"`    // minimum rarity tier
	MaxRarity    *int     `yaml:"max_rarity,omitempty"`
	BaseType     *string  `yaml:"base_type,omitempty"`     // e.g., "Diadem", "Monarch"
	HasProperty  *string  `yaml:"has_property,omitempty"`  // item has this property key
	PropertyGTE  map[string]int `yaml:"property_gte,omitempty"` // property >= value
}

// Action defines what to do when a rule matches.
type Action string

const (
	ActionPickup Action = "pickup"
	ActionIgnore Action = "ignore"
	ActionAlert  Action = "alert"  // pickup + send notification
)

// Rule is a single loot filter rule.
type Rule struct {
	Name      string    `yaml:"name,omitempty"`
	Match     Condition `yaml:"match"`
	Action    Action    `yaml:"action"`
	Priority  int       `yaml:"priority,omitempty"`
}

// RuleEngine evaluates items against a list of rules.
type RuleEngine struct {
	Rules []Rule
}

// NewRuleEngine creates a rule engine from a list of rules.
func NewRuleEngine(rules []Rule) *RuleEngine {
	return &RuleEngine{Rules: rules}
}

// Evaluate checks an item against all rules.
// Returns the first matching rule's action and priority.
func (e *RuleEngine) Evaluate(item plugin.DetectedItem) (action Action, priority int, matched bool) {
	for _, rule := range e.Rules {
		if e.matches(rule.Match, item) {
			p := rule.Priority
			if p == 0 {
				p = PriorityNormal
			}
			return rule.Action, p, true
		}
	}
	return ActionIgnore, 0, false
}

// ShouldPickup implements plugin.LootFilter.
func (e *RuleEngine) ShouldPickup(item plugin.DetectedItem) (bool, int) {
	action, priority, matched := e.Evaluate(item)
	if !matched {
		return false, 0
	}
	return action == ActionPickup || action == ActionAlert, priority
}

// ShouldAlert implements plugin.LootFilter.
func (e *RuleEngine) ShouldAlert(item plugin.DetectedItem) bool {
	action, _, matched := e.Evaluate(item)
	return matched && action == ActionAlert
}

func (e *RuleEngine) matches(cond Condition, item plugin.DetectedItem) bool {
	if cond.Type != nil && !strings.EqualFold(item.Type, *cond.Type) {
		return false
	}
	if cond.NameContains != nil && !strings.Contains(strings.ToLower(item.Name), strings.ToLower(*cond.NameContains)) {
		return false
	}
	if cond.NameExact != nil && !strings.EqualFold(item.Name, *cond.NameExact) {
		return false
	}
	if cond.MinRarity != nil && item.Rarity < *cond.MinRarity {
		return false
	}
	if cond.MaxRarity != nil && item.Rarity > *cond.MaxRarity {
		return false
	}
	if cond.BaseType != nil && !strings.EqualFold(item.Properties["base_type"], *cond.BaseType) {
		return false
	}
	if cond.HasProperty != nil {
		if _, ok := item.Properties[*cond.HasProperty]; !ok {
			return false
		}
	}
	for key, minVal := range cond.PropertyGTE {
		// TODO: Parse property value as int and compare
		_ = key
		_ = minVal
	}
	return true
}
