package room

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/sdaduanbilei/agent-team/internal/agent"
	"gopkg.in/yaml.v3"
)

// extractTitle 从文档内容中提取标题
func extractTitle(content string) string {
	for _, line := range strings.Split(content, "\n") {
		line = strings.TrimSpace(line)
		if strings.HasPrefix(line, "# ") {
			return strings.TrimPrefix(line, "# ")
		}
	}
	if idx := strings.Index(content, "《"); idx != -1 {
		if end := strings.Index(content[idx:], "》"); end != -1 {
			return content[idx+len("《") : idx+end]
		}
	}
	for _, line := range strings.Split(content, "\n") {
		line = strings.TrimSpace(line)
		if strings.HasPrefix(line, "## ") {
			return strings.TrimPrefix(line, "## ")
		}
	}
	return ""
}

// titleToFilename 从文档标题生成文件名，如 "主角小传：林远" → "主角小传-林远.md"
func titleToFilename(title, agentName string) string {
	if title == "" {
		return fmt.Sprintf("%s-%s.md", agentName, time.Now().Format("20060102-150405"))
	}
	name := strings.NewReplacer(
		"：", "-", ":", "-",
		"/", "-", "\\", "-",
		" ", "-", "　", "-",
		"*", "", "?", "", "\"", "", "<", "", ">", "", "|", "",
	).Replace(title)
	for strings.Contains(name, "--") {
		name = strings.ReplaceAll(name, "--", "-")
	}
	name = strings.Trim(name, "-")
	if name == "" {
		return fmt.Sprintf("%s-%s.md", agentName, time.Now().Format("20060102-150405"))
	}
	return name + ".md"
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// parseAssignments 解析任务分配指令。
// 支持多行任务描述：从 @成员名 开始，到下一个 @成员名 或文本结束为止。
func parseAssignments(text string) map[string]string {
	result := make(map[string]string)
	lines := strings.Split(text, "\n")

	var currentName string
	var currentTask strings.Builder

	flush := func() {
		if currentName != "" {
			task := strings.TrimSpace(currentTask.String())
			if task != "" {
				result[currentName] = task
			}
		}
		currentName = ""
		currentTask.Reset()
	}

	for _, line := range lines {
		trimmed := strings.TrimSpace(line)
		atIdx := strings.Index(trimmed, "@")
		if atIdx >= 0 {
			rest := trimmed[atIdx+1:]
			if idx := strings.IndexAny(rest, " \t"); idx > 0 {
				name := strings.TrimSpace(rest[:idx])
				task := strings.TrimSpace(rest[idx+1:])
				flush()
				currentName = name
				if task != "" {
					currentTask.WriteString(task)
				}
				continue
			}
			name := strings.TrimSpace(rest)
			if name != "" {
				flush()
				currentName = name
				continue
			}
		}
		if strings.HasPrefix(trimmed, "ASSIGN:") {
			parts := strings.SplitN(strings.TrimPrefix(trimmed, "ASSIGN:"), ":", 2)
			if len(parts) == 2 {
				flush()
				result[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
			}
			continue
		}
		if currentName != "" && trimmed != "" {
			if currentTask.Len() > 0 {
				currentTask.WriteString("\n")
			}
			currentTask.WriteString(trimmed)
		}
	}
	flush()
	return result
}

// parseUserMentions 从用户消息中提取 @agent 指派。
func parseUserMentions(text string, validMembers map[string]*agent.Agent) map[string]string {
	assignments := make(map[string]string)
	for _, line := range strings.Split(text, "\n") {
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "@") {
			continue
		}
		rest := strings.TrimPrefix(line, "@")
		idx := strings.IndexAny(rest, " \t")
		if idx <= 0 {
			continue
		}
		name := strings.TrimSpace(rest[:idx])
		task := strings.TrimSpace(rest[idx+1:])
		if _, ok := validMembers[name]; ok && task != "" {
			assignments[name] = task
		}
	}
	return assignments
}

// isConversational 判断用户 @成员 后的文本是对话还是任务分配
func isConversational(text string) bool {
	text = strings.TrimSpace(text)
	runeLen := len([]rune(text))

	// 非常短的消息视为对话
	if runeLen < 10 {
		return true
	}

	// 问候/简短回复
	lower := strings.ToLower(text)
	greetings := []string{"你好", "嗨", "hi", "hello", "hey", "谢谢", "感谢", "好的", "ok", "好", "嗯", "对", "是的", "不是", "怎么样", "什么"}
	for _, g := range greetings {
		if strings.HasPrefix(lower, g) {
			return true
		}
	}

	// 以问号结尾的短消息视为提问（对话）
	if runeLen < 30 && (strings.HasSuffix(text, "?") || strings.HasSuffix(text, "？")) {
		return true
	}

	return false
}

func parseRoomConfig(data []byte) (Config, error) {
	var cfg Config
	if !bytes.HasPrefix(data, []byte("---")) {
		return cfg, fmt.Errorf("missing frontmatter")
	}
	parts := bytes.SplitN(data, []byte("---"), 3)
	if len(parts) < 3 {
		return cfg, fmt.Errorf("invalid frontmatter")
	}
	return cfg, yaml.Unmarshal(parts[1], &cfg)
}

// resolveAgentPath finds agent dir: prefers agentsDir/team/name, falls back to agentsDir/name
func resolveAgentPath(agentsDir, team, name string) string {
	if team != "" {
		p := filepath.Join(agentsDir, team, name)
		if _, err := os.Stat(p); err == nil {
			return p
		}
	}
	return filepath.Join(agentsDir, name)
}
