package background

import (
	"log"
	"strings"
	"time"
)

// ProactiveDecision represents a decision about whether to send a proactive message.
type ProactiveDecision struct {
	ShouldSend bool   `json:"should_send"`
	Urgency    string `json:"urgency"` // low, medium, high
	Reason     string `json:"reason"`
}

// ProactiveGuard evaluates whether a proactive message should be sent
// based on time-of-day, urgency, rate limits, and user state.
type ProactiveGuard struct {
	// Quiet hours: no non-urgent messages during this window
	QuietHoursStart int // 0-23, default 23
	QuietHoursEnd   int // 0-23, default 7

	// Min gap between proactive messages, by urgency
	MinGapByUrgency map[string]time.Duration

	// Max proactive messages per hour
	MaxMessagesPerHour int

	// Track recent send times for rate limiting
	recentSends []time.Time
}

// DefaultProactiveGuard returns a guard with sensible defaults.
func DefaultProactiveGuard() *ProactiveGuard {
	return &ProactiveGuard{
		QuietHoursStart: 23,
		QuietHoursEnd:   7,
		MinGapByUrgency: map[string]time.Duration{
			"low":    15 * time.Minute,
			"medium": 5 * time.Minute,
			"high":   1 * time.Minute,
		},
		MaxMessagesPerHour: 5,
	}
}

// IsQuietHour returns true if the given time falls within quiet hours.
func (g *ProactiveGuard) IsQuietHour(now time.Time) bool {
	hour := now.Hour()
	if g.QuietHoursStart < g.QuietHoursEnd {
		return hour >= g.QuietHoursStart && hour < g.QuietHoursEnd
	}
	// Overnight quiet hours (e.g., 23:00 - 07:00)
	return hour >= g.QuietHoursStart || hour < g.QuietHoursEnd
}

// Evaluate checks whether a proactive message should be sent.
func (g *ProactiveGuard) Evaluate(now time.Time, lastProactiveTime time.Time, urgency string, userState string) ProactiveDecision {
	// 1. Quiet hours: only high urgency messages pass
	if g.IsQuietHour(now) && urgency != "high" {
		return ProactiveDecision{
			ShouldSend: false,
			Urgency:    urgency,
			Reason:     "当前处于安静时段（23:00-07:00），仅紧急消息可推送",
		}
	}

	// 2. User state check: don't disturb if user is resting/busy
	if userState == "resting" || userState == "busy" || userState == "sleeping" {
		if urgency != "high" {
			return ProactiveDecision{
				ShouldSend: false,
				Urgency:    urgency,
				Reason:     "开拓者正在休息/忙碌，不打扰",
			}
		}
	}

	// 3. Rate limit by urgency
	minGap, ok := g.MinGapByUrgency[urgency]
	if !ok {
		minGap = g.MinGapByUrgency["low"]
	}
	if !lastProactiveTime.IsZero() && now.Sub(lastProactiveTime) < minGap {
		return ProactiveDecision{
			ShouldSend: false,
			Urgency:    urgency,
			Reason:     "距上次主动消息时间过短（" + minGap.String() + " 最小间隔）",
		}
	}

	// 4. Hourly rate limit
	g.pruneOldSends(now)
	if len(g.recentSends) >= g.MaxMessagesPerHour {
		return ProactiveDecision{
			ShouldSend: false,
			Urgency:    urgency,
			Reason:     "本小时主动消息已达上限",
		}
	}

	// 5. Content length validation (caller should also check)
	return ProactiveDecision{
		ShouldSend: true,
		Urgency:    urgency,
		Reason:     "",
	}
}

// RecordSend records a proactive message send for rate limiting.
func (g *ProactiveGuard) RecordSend(now time.Time) {
	g.recentSends = append(g.recentSends, now)
	g.pruneOldSends(now)
}

// pruneOldSends removes sends older than 1 hour.
func (g *ProactiveGuard) pruneOldSends(now time.Time) {
	cutoff := now.Add(-1 * time.Hour)
	valid := g.recentSends[:0]
	for _, t := range g.recentSends {
		if t.After(cutoff) {
			valid = append(valid, t)
		}
	}
	g.recentSends = valid
}

// ExtractUrgencyFromContent tries to infer urgency from the proactive message content.
func ExtractUrgencyFromContent(content string) string {
	lower := strings.ToLower(content)

	// High urgency indicators
	highIndicators := []string{"紧急", "立刻", "马上", "危险", "警告", "报警", "异常", "urgent", "alert"}
	for _, kw := range highIndicators {
		if strings.Contains(lower, kw) {
			return "high"
		}
	}

	// Medium urgency indicators
	mediumIndicators := []string{"建议", "提醒", "注意", "该", "要", "应该", "记得", "别忘了"}
	for _, kw := range mediumIndicators {
		if strings.Contains(lower, kw) {
			return "medium"
		}
	}

	return "low"
}

// ValidateProactiveMessage performs post-extraction validation on a message.
func ValidateProactiveMessage(content string) (valid bool, reason string) {
	runes := []rune(content)
	if len(runes) == 0 {
		return false, "消息为空"
	}
	if len(runes) > 500 {
		return false, "消息过长（>500字符）"
	}

	// Check for prohibited patterns (should not tell user they're resting when they're active)
	prohibited := []string{
		"系统检测到", "根据分析", "经检测", "后台监控",
	}
	for _, p := range prohibited {
		if strings.Contains(content, p) {
			return false, "包含机械语言: " + p
		}
	}

	return true, ""
}

// DetermineUserState checks conversation history for user state indicators.
func DetermineUserState(lastUserMsg string) string {
	lower := strings.ToLower(lastUserMsg)
	restIndicators := []string{"睡", "休息", "躺", "困", "累", "晚安", "午安", "小憩"}
	busyIndicators := []string{"忙", "工作", "开会", "出去", "走了", "拜拜", "再见", "回头", "晚点"}

	for _, kw := range restIndicators {
		if strings.Contains(lower, kw) {
			return "resting"
		}
	}
	for _, kw := range busyIndicators {
		if strings.Contains(lower, kw) {
			return "busy"
		}
	}
	return "active"
}

// logDecision logs the proactive decision for debugging.
func logDecision(d ProactiveDecision) {
	if d.ShouldSend {
		log.Printf("[主动消息决策] 允许推送 (紧急程度=%s)", d.Urgency)
	} else {
		log.Printf("[主动消息决策] 阻止推送 (紧急程度=%s, 原因=%s)", d.Urgency, d.Reason)
	}
}
