package persona

import (
	"log"
	"sync"
	"time"
)

// MoodTransition records a change from one mood to another.
type MoodTransition struct {
	From      string    `json:"from"`
	To        string    `json:"to"`
	Reason    string    `json:"reason"`
	Timestamp time.Time `json:"timestamp"`
}

// EmotionState is the current emotional state of the persona.
type EmotionState struct {
	CurrentMood       string           `json:"current_mood"`
	Intensity         float64          `json:"intensity"` // 0.0 - 1.0
	DominantSentiment string           `json:"dominant_sentiment"`
	SentimentCounts   map[string]int   `json:"sentiment_counts"`
	MoodHistory       []MoodTransition `json:"mood_history"`
	LastUpdated       time.Time        `json:"last_updated"`
}

// EmotionTracker manages emotional state for a single user.
// Tracks mood, intensity, sentiment accumulation, and triggers transitions.
type EmotionTracker struct {
	mu                sync.Mutex
	state             EmotionState
	moodConfig        []MoodConfig // from YAML mood_system
	positiveThreshold int          // sentiment count to trigger positive transition
	negativeThreshold int          // sentiment count to trigger negative transition
	maxHistory        int          // max mood history entries
}

// NewEmotionTracker creates a new tracker from YAML mood config.
func NewEmotionTracker(moodSystem []MoodConfig) *EmotionTracker {
	return &EmotionTracker{
		state: EmotionState{
			CurrentMood:       "thoughtful",
			Intensity:         0.3,
			DominantSentiment: "neutral",
			SentimentCounts:   map[string]int{"positive": 0, "neutral": 0, "negative": 0},
			MoodHistory:       make([]MoodTransition, 0, 20),
			LastUpdated:       time.Now(),
		},
		moodConfig:        moodSystem,
		positiveThreshold: 3,
		negativeThreshold: 3,
		maxHistory:        20,
	}
}

// RecordSentiment records a user sentiment and potentially triggers mood transitions.
func (t *EmotionTracker) RecordSentiment(sentiment string) {
	t.mu.Lock()
	defer t.mu.Unlock()

	t.state.SentimentCounts[sentiment]++
	t.state.LastUpdated = time.Now()

	total := t.state.SentimentCounts["positive"] + t.state.SentimentCounts["neutral"] + t.state.SentimentCounts["negative"]
	if total > 0 {
		posRatio := float64(t.state.SentimentCounts["positive"]) / float64(total)
		negRatio := float64(t.state.SentimentCounts["negative"]) / float64(total)
		switch {
		case posRatio > 0.5:
			t.state.DominantSentiment = "positive"
		case negRatio > 0.5:
			t.state.DominantSentiment = "negative"
		default:
			t.state.DominantSentiment = "neutral"
		}
	}

	posCount := t.state.SentimentCounts["positive"]
	negCount := t.state.SentimentCounts["negative"]

	if posCount >= t.positiveThreshold && t.state.CurrentMood != "happy" && t.state.CurrentMood != "playful" {
		if t.state.Intensity > 0.6 {
			t.applyMoodTransition("playful", "积极情绪积累")
		} else {
			t.applyMoodTransition("happy", "积极情绪积累")
		}
		t.state.SentimentCounts["positive"] = 0
	}

	if negCount >= t.negativeThreshold && t.state.CurrentMood != "worried" {
		t.applyMoodTransition("worried", "消极情绪积累")
		t.state.SentimentCounts["negative"] = 0
	}
}

// UpdateMood explicitly changes mood for significant events.
func (t *EmotionTracker) UpdateMood(trigger string) {
	t.mu.Lock()
	defer t.mu.Unlock()

	switch trigger {
	case "user_returned":
		t.applyMoodTransition("happy", "开拓者回来了")
	case "long_silence":
		if t.state.CurrentMood != "thoughtful" && t.state.CurrentMood != "nostalgic" {
			t.applyMoodTransition("thoughtful", "长时间没有交流")
		}
	case "deep_conversation":
		t.applyMoodTransition("thoughtful", "深度对话后")
	case "nostalgic_trigger":
		t.applyMoodTransition("nostalgic", "触及回忆")
	}
}

// GetCurrentMood returns the current mood, its YAML expression, and intensity.
func (t *EmotionTracker) GetCurrentMood() (mood string, expression string, intensity float64) {
	t.mu.Lock()
	defer t.mu.Unlock()

	mood = t.state.CurrentMood
	intensity = t.state.Intensity

	for _, mc := range t.moodConfig {
		if mc.Mood == mood {
			expression = mc.Expression
			break
		}
	}
	return
}

// Decay reduces intensity over time, drifting toward "thoughtful" baseline.
func (t *EmotionTracker) Decay() {
	t.mu.Lock()
	defer t.mu.Unlock()

	hoursSinceUpdate := time.Since(t.state.LastUpdated).Hours()
	decayAmount := hoursSinceUpdate * 0.1

	t.state.Intensity -= decayAmount
	if t.state.Intensity < 0.1 {
		t.state.Intensity = 0.1
	}

	if t.state.Intensity < 0.2 && t.state.CurrentMood != "thoughtful" {
		t.applyMoodTransition("thoughtful", "情绪自然消退")
	}
}

// applyMoodTransition internal mood change with hysteresis.
func (t *EmotionTracker) applyMoodTransition(newMood, reason string) {
	if t.state.CurrentMood == newMood {
		return
	}
	oldMood := t.state.CurrentMood
	t.state.CurrentMood = newMood
	t.state.Intensity = 0.5 + t.state.Intensity*0.3
	if t.state.Intensity > 1.0 {
		t.state.Intensity = 1.0
	}

	transition := MoodTransition{
		From:      oldMood,
		To:        newMood,
		Reason:    reason,
		Timestamp: time.Now(),
	}
	t.state.MoodHistory = append(t.state.MoodHistory, transition)
	if len(t.state.MoodHistory) > t.maxHistory {
		t.state.MoodHistory = t.state.MoodHistory[1:]
	}

	log.Printf("[情感] 心情转变: %s -> %s (原因: %s, 强度: %.2f)", oldMood, newMood, reason, t.state.Intensity)
}

// GetState returns a copy of the current emotion state.
func (t *EmotionTracker) GetState() EmotionState {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.state
}
