package achievements

import "time"

// Requirement represents a single achievement requirement
type Requirement struct {
	AchievementID uint32 `json:"achievement_id"`
	Name          string `json:"name"`
	QtyRequired   uint32 `json:"qty_required"`
}

// Reward represents a single achievement reward
type Reward struct {
	AchievementID uint32 `json:"achievement_id"`
	Reward        string `json:"reward"`
}

// Achievement represents a complete achievement definition
type Achievement struct {
	ID              uint32        `json:"id"`
	Title           string        `json:"title"`
	UncompletedText string        `json:"uncompleted_text"`
	CompletedText   string        `json:"completed_text"`
	Category        string        `json:"category"`
	Expansion       string        `json:"expansion"`
	Icon            uint16        `json:"icon"`
	PointValue      uint32        `json:"point_value"`
	QtyRequired     uint32        `json:"qty_required"`
	Hide            bool          `json:"hide"`
	Unknown3A       uint32        `json:"unknown3a"`
	Unknown3B       uint32        `json:"unknown3b"`
	Requirements    []Requirement `json:"requirements"`
	Rewards         []Reward      `json:"rewards"`
}

// UpdateItem represents a single achievement progress update
type UpdateItem struct {
	AchievementID uint32 `json:"achievement_id"`
	ItemUpdate    uint32 `json:"item_update"`
}

// Update represents achievement completion/progress data
type Update struct {
	ID            uint32       `json:"id"`
	CompletedDate time.Time    `json:"completed_date"`
	UpdateItems   []UpdateItem `json:"update_items"`
}

// NewAchievement creates a new achievement with empty slices
func NewAchievement() *Achievement {
	return &Achievement{
		Requirements: make([]Requirement, 0),
		Rewards:      make([]Reward, 0),
	}
}

// NewUpdate creates a new achievement update with empty slices
func NewUpdate() *Update {
	return &Update{
		UpdateItems: make([]UpdateItem, 0),
	}
}

// AddRequirement adds a requirement to the achievement
func (a *Achievement) AddRequirement(req Requirement) {
	a.Requirements = append(a.Requirements, req)
}

// AddReward adds a reward to the achievement
func (a *Achievement) AddReward(reward Reward) {
	a.Rewards = append(a.Rewards, reward)
}

// AddUpdateItem adds an update item to the achievement update
func (u *Update) AddUpdateItem(item UpdateItem) {
	u.UpdateItems = append(u.UpdateItems, item)
}

// Clone creates a deep copy of the achievement
func (a *Achievement) Clone() *Achievement {
	clone := &Achievement{
		ID:              a.ID,
		Title:           a.Title,
		UncompletedText: a.UncompletedText,
		CompletedText:   a.CompletedText,
		Category:        a.Category,
		Expansion:       a.Expansion,
		Icon:            a.Icon,
		PointValue:      a.PointValue,
		QtyRequired:     a.QtyRequired,
		Hide:            a.Hide,
		Unknown3A:       a.Unknown3A,
		Unknown3B:       a.Unknown3B,
		Requirements:    make([]Requirement, len(a.Requirements)),
		Rewards:         make([]Reward, len(a.Rewards)),
	}

	copy(clone.Requirements, a.Requirements)
	copy(clone.Rewards, a.Rewards)
	return clone
}

// Clone creates a deep copy of the achievement update
func (u *Update) Clone() *Update {
	clone := &Update{
		ID:            u.ID,
		CompletedDate: u.CompletedDate,
		UpdateItems:   make([]UpdateItem, len(u.UpdateItems)),
	}

	copy(clone.UpdateItems, u.UpdateItems)
	return clone
}
