package fights

import (
	"fmt"
	"strings"
	"time"
)

// ActionEntry represents a compacted fight action log. This allows us to store more logs
// in the same space as a single string.
type ActionEntry struct {
	Type int    `json:"t"`
	Data int    `json:"d,omitempty"`
	Name string `json:"n,omitempty"` // For spell names
}

// Action type constants
const (
	ActionAttackHit     = 1
	ActionAttackMiss    = 2
	ActionSpellHeal     = 3
	ActionSpellHurt     = 4
	ActionRunSuccess    = 5
	ActionRunFail       = 6
	ActionGeneric       = 7
	ActionMonsterAttack = 8
	ActionMonsterMiss   = 9
	ActionMonsterSpell  = 10
	ActionMonsterDeath  = 11
)

func (f *Fight) AddAction(action string) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionGeneric, Name: action})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionAttackHit(damage int) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionAttackHit, Data: damage})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionAttackMiss() {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionAttackMiss})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionSpellHeal(spellName string, healAmount int) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionSpellHeal, Data: healAmount, Name: spellName})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionSpellHurt(spellName string, damage int) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionSpellHurt, Data: damage, Name: spellName})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionRunSuccess() {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionRunSuccess})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionRunFail() {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionRunFail})
	f.Updated = time.Now().Unix()
}

// Convert actions to human-readable strings
func (f *Fight) GetActions() []string {
	result := make([]string, len(f.Actions))
	for i, action := range f.Actions {
		result[i] = f.actionToString(action)
	}
	return result
}

func (f *Fight) GetLastAction() string {
	if len(f.Actions) == 0 {
		return ""
	}
	return f.actionToString(f.Actions[len(f.Actions)-1])
}

func (f *Fight) ClearActions() {
	f.Actions = make([]ActionEntry, 0)
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionMonsterAttack(monsterName string, damage int) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionMonsterAttack, Data: damage, Name: monsterName})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionMonsterMiss(monsterName string) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionMonsterMiss, Name: monsterName})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionMonsterSpell(monsterName, spellName string, damage int) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionMonsterSpell, Data: damage, Name: monsterName + "|" + spellName})
	f.Updated = time.Now().Unix()
}

func (f *Fight) AddActionMonsterDeath(monsterName string) {
	f.Actions = append(f.Actions, ActionEntry{Type: ActionMonsterDeath, Name: monsterName})
	f.Updated = time.Now().Unix()
}

// Update actionToString method - add these cases
func (f *Fight) actionToString(action ActionEntry) string {
	switch action.Type {
	case ActionAttackHit:
		return fmt.Sprintf("You attacked for %d damage!", action.Data)
	case ActionAttackMiss:
		return "You missed your attack!"
	case ActionSpellHeal:
		return fmt.Sprintf("You cast %s and healed %d HP!", action.Name, action.Data)
	case ActionSpellHurt:
		return fmt.Sprintf("You cast %s and dealt %d damage!", action.Name, action.Data)
	case ActionRunSuccess:
		return "You successfully ran away!"
	case ActionRunFail:
		return "You failed to run away!"
	case ActionGeneric:
		return action.Name
	case ActionMonsterAttack:
		return fmt.Sprintf("%s attacks for %d damage!", action.Name, action.Data)
	case ActionMonsterMiss:
		return fmt.Sprintf("%s missed its attack!", action.Name)
	case ActionMonsterSpell:
		parts := strings.Split(action.Name, "|")
		if len(parts) == 2 {
			return fmt.Sprintf("%s casts %s for %d damage!", parts[0], parts[1], action.Data)
		}
		return fmt.Sprintf("%s casts a spell for %d damage!", action.Name, action.Data)
	case ActionMonsterDeath:
		return fmt.Sprintf("%s has been defeated!", action.Name)
	default:
		return "Unknown action"
	}
}
