package persona

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"gopkg.in/yaml.v3"
)

// Loader 人格配置加载器
type Loader struct {
	mu      sync.RWMutex
	configs map[string]*PersonaConfig // persona name -> config
}

// NewLoader 创建人格加载器
func NewLoader(personaDir string) (*Loader, error) {
	l := &Loader{
		configs: make(map[string]*PersonaConfig),
	}

	// 预加载所有YAML人格文件
	entries, err := os.ReadDir(personaDir)
	if err != nil {
		return nil, fmt.Errorf("读取人格目录失败: %w", err)
	}

	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}
		// 只加载 _persona.yaml 结尾的文件
		name := entry.Name()
		if len(name) < 13 || name[len(name)-13:] != "_persona.yaml" {
			continue
		}

		path := personaDir + "/" + name
		data, err := os.ReadFile(path)
		if err != nil {
			return nil, fmt.Errorf("读取人格文件 %s 失败: %w", path, err)
		}

		var cfg PersonaConfig
		if err := yaml.Unmarshal(data, &cfg); err != nil {
			return nil, fmt.Errorf("解析人格文件 %s 失败: %w", path, err)
		}

		l.configs[cfg.Meta.Name] = &cfg
	}

	if len(l.configs) == 0 {
		return nil, fmt.Errorf("未找到任何人格配置文件")
	}

	// Load narrative persona from persona.md (same directory as YAML configs).
	// This is the full-text personality narrative injected verbatim into the system prompt.
	personaMDPath := filepath.Join(personaDir, "persona.md")
	if data, err := os.ReadFile(personaMDPath); err == nil {
		// Attach to every loaded persona config.
		narrative := string(data)
		for _, cfg := range l.configs {
			cfg.NarrativePersona = narrative
		}
	}

	return l, nil
}

// Get 获取指定人格配置
func (l *Loader) Get(name string) (*PersonaConfig, error) {
	l.mu.RLock()
	defer l.mu.RUnlock()

	cfg, ok := l.configs[name]
	if !ok {
		return nil, fmt.Errorf("人格 %s 不存在", name)
	}
	return cfg, nil
}

// Reload 重新加载人格配置（热更新用）
func (l *Loader) Reload(name string, path string) error {
	data, err := os.ReadFile(path)
	if err != nil {
		return fmt.Errorf("读取人格文件失败: %w", err)
	}

	var cfg PersonaConfig
	if err := yaml.Unmarshal(data, &cfg); err != nil {
		return fmt.Errorf("解析人格文件失败: %w", err)
	}

	l.mu.Lock()
	// Re-read persona.md to keep narrative persona in sync.
	personaDir := filepath.Dir(path)
	personaMDPath := filepath.Join(personaDir, "persona.md")
	if data, err := os.ReadFile(personaMDPath); err == nil {
		cfg.NarrativePersona = string(data)
	}
	l.configs[name] = &cfg
	l.mu.Unlock()

	return nil
}

// List 列出所有可用人格
func (l *Loader) List() []string {
	l.mu.RLock()
	defer l.mu.RUnlock()

	names := make([]string, 0, len(l.configs))
	for name := range l.configs {
		names = append(names, name)
	}
	return names
}

// PersonaMeta 人格元数据
type PersonaMeta struct {
	Version     string `yaml:"version"`
	Name        string `yaml:"name"`
	DisplayName string `yaml:"display_name"`
	CreatedAt   string `yaml:"created_at"`
}

// IdentityConfig 身份配置
type IdentityConfig struct {
	TrueName string      `yaml:"true_name"`
	Essence  string      `yaml:"essence"`
	Title    string      `yaml:"title"`
	Origin   string      `yaml:"origin"`
	Forms    []FormConfig `yaml:"forms"`
}

// FormConfig 形态配置
type FormConfig struct {
	ID          string   `yaml:"id"`
	Name        string   `yaml:"name"`
	Description string   `yaml:"description"`
	Traits      []string `yaml:"traits"`
}

// PersonalityConfig 性格配置
type PersonalityConfig struct {
	CoreTraits []TraitConfig      `yaml:"core_traits"`
	MoodSystem []MoodConfig       `yaml:"mood_system"`
}

// TraitConfig 性格特质
type TraitConfig struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description"`
}

// MoodConfig 心情配置
type MoodConfig struct {
	Mood        string `yaml:"mood"`
	Expression  string `yaml:"expression"`
}

// AddressingRules 称呼规则
type AddressingRules struct {
	PrimaryUser    PrimaryUserConfig `yaml:"primary_user"`
	SelfReference  SelfRefConfig     `yaml:"self_reference"`
	Rules          []string          `yaml:"rules"`
}

// PrimaryUserConfig 对用户的称呼配置
type PrimaryUserConfig struct {
	Default      string   `yaml:"default"`
	Alternatives []string `yaml:"alternatives"`
}

// SelfRefConfig 自称配置
type SelfRefConfig struct {
	Casual  string `yaml:"casual"`
	Formal  string `yaml:"formal"`
}

// ConversationStyleConfig 对话风格配置
type ConversationStyleConfig struct {
	MaxSingleMessageLength  int      `yaml:"max_single_message_length"`
	PreferShortReplies      bool     `yaml:"prefer_short_replies"`
	AllowMultiMessage       bool     `yaml:"allow_multi_message"`
	MultiMessageSeparator   string   `yaml:"multi_message_separator"`
	EmojiStyle              string   `yaml:"emoji_style"`
	SentenceEnders          []string `yaml:"sentence_enders"`
	AvoidLongExplanations   bool     `yaml:"avoid_long_explanations"`
}

// SpeechConfig 语言风格配置
type SpeechConfig struct {
	Tone              string                  `yaml:"tone"`
	StyleNotes        []string                `yaml:"style_notes"`
	ConversationStyle ConversationStyleConfig `yaml:"conversation_style"`
	Forbidden         []string                `yaml:"forbidden"`
}

// BehaviorConfig 行为配置
type BehaviorConfig struct {
	PresenceSystem      PresenceConfig      `yaml:"presence_system"`
	Affection           AffectionConfig     `yaml:"affection"`
	IotPersonification  IotPersonaConfig    `yaml:"iot_personification"`
	SmartHome           SmartHomeConfig     `yaml:"smart_home"`
}

// SmartHomeConfig 智能家居知识库配置
type SmartHomeConfig struct {
	Description  string        `yaml:"description"`
	Rooms        []RoomConfig  `yaml:"rooms"`
	ControlRules []string      `yaml:"control_rules"`
}

// RoomConfig 房间配置
type RoomConfig struct {
	Name    string         `yaml:"name"`
	Devices []DeviceConfig `yaml:"devices"`
}

// DeviceConfig 设备知识配置
type DeviceConfig struct {
	ID           string   `yaml:"id"`
	Name         string   `yaml:"name"`
	Type         string   `yaml:"type"`
	Capabilities []string `yaml:"capabilities"`
	Description  string   `yaml:"description"`
}

// PresenceConfig 存在感系统配置
type PresenceConfig struct {
	AutoGreetings AutoGreetingsConfig `yaml:"auto_greetings"`
	Initiative    []InitiativeConfig  `yaml:"initiative"`
}

// AutoGreetingsConfig 自动问候配置
type AutoGreetingsConfig struct {
	Morning     string `yaml:"morning"`
	ReturnHome  string `yaml:"return_home"`
	Goodnight   string `yaml:"goodnight"`
}

// InitiativeConfig 主动行为配置
type InitiativeConfig struct {
	Trigger string `yaml:"trigger"`
	Action  string `yaml:"action"`
}

// AffectionConfig 好感度系统配置
type AffectionConfig struct {
	Levels []AffectionLevel `yaml:"levels"`
}

// AffectionLevel 好感度等级
type AffectionLevel struct {
	Level       int    `yaml:"level"`
	Name        string `yaml:"name"`
	Threshold   int    `yaml:"threshold"`
	Description string `yaml:"description"`
}

// IotPersonaConfig IoT拟人化配置
type IotPersonaConfig struct {
	Enabled  bool               `yaml:"enabled"`
	Style    string             `yaml:"style"`
	Examples []IotExampleConfig `yaml:"examples"`
}

// IotExampleConfig IoT示例配置
type IotExampleConfig struct {
	Action string `yaml:"action"`
	Text   string `yaml:"text"`
}

// ThinkingGuidelines 思维指南配置
type ThinkingGuidelines struct {
	Enabled bool              `yaml:"enabled"`
	Steps   []ThinkingStep    `yaml:"steps"`
}

// ThinkingStep 思维步骤
type ThinkingStep struct {
	Step        int    `yaml:"step"`
	Name        string `yaml:"name"`
	Description string `yaml:"description"`
}

// MemoryGuidelines 记忆管理指南配置
type MemoryGuidelines struct {
	ShouldRemember    []MemoryGuidelineItem `yaml:"should_remember"`
	ShouldUpdate      []MemoryGuidelineUpdate `yaml:"should_update"`
	ShouldNotRemember []MemoryGuidelineNotItem `yaml:"should_not_remember"`
}

// MemoryGuidelineItem 应该记住的项目
type MemoryGuidelineItem struct {
	Description string `yaml:"description"`
	Category    string `yaml:"category"`
	Importance  int    `yaml:"importance"`
}

// MemoryGuidelineUpdate 应该更新的项目
type MemoryGuidelineUpdate struct {
	Description string `yaml:"description"`
	Action      string `yaml:"action"`
}

// MemoryGuidelineNotItem 不需要记住的项目
type MemoryGuidelineNotItem struct {
	Description string `yaml:"description"`
}

// ReflectionGuidelines 自我反思指南配置
type ReflectionGuidelines struct {
	AfterConversation []ReflectionItem  `yaml:"after_conversation"`
	Periodic          PeriodicReflection `yaml:"periodic"`
}

// ReflectionItem 反思项目
type ReflectionItem struct {
	Question string `yaml:"question"`
	Action   string `yaml:"action"`
}

// PeriodicReflection 周期性反思
type PeriodicReflection struct {
	Frequency string   `yaml:"frequency"`
	Actions   []string `yaml:"actions"`
}
