package room

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"sync"

	"github.com/sdaduanbilei/agent-team/internal/agent"
	"github.com/sdaduanbilei/agent-team/internal/llm"
	"github.com/sdaduanbilei/agent-team/internal/prompt"
	"github.com/sdaduanbilei/agent-team/internal/skill"
	"github.com/sdaduanbilei/agent-team/internal/store"
	"github.com/sdaduanbilei/agent-team/internal/user"
)

type RoomType string

const (
	TypeProject RoomType = "project"
)

type Status string

const (
	StatusPending  Status = "pending"
	StatusThinking Status = "thinking"
	StatusWorking  Status = "working"
)

type Config struct {
	Name    string   `yaml:"name"`
	Type    RoomType `yaml:"type"`
	Master  string   `yaml:"master"`  // agent name
	Members []string `yaml:"members"` // agent names
	Color   string   `yaml:"color"`   // avatar color
	Team    string   `yaml:"team"`    // installed team name
}

type Room struct {
	Config    Config
	Dir       string
	master    *agent.Agent
	members   map[string]*agent.Agent
	skillMeta []skill.Meta
	User      *user.User
	Status    Status
	ActiveAgent string // for working status display
	Broadcast func(Event) // set by api layer

	// master 的会话历史，保持多轮对话上下文
	masterHistory []llm.Message
	historyMu     sync.Mutex

	Mode               string            // "plan" | "build"
	pendingAssignments map[string]string // plan 模式下暂存的待执行任务
	pendingPlanReply   string            // master 规划原文，用于生成计划文档

	// Build 模式下成员对话跟踪
	memberConvos     map[string][]llm.Message // 成员名 -> 多轮对话历史
	memberArtifacts  map[string]string        // 成员名 -> 已产出的文档文件名（用于后续覆盖更新）
	lastActiveMember string                   // 最后一个发出提问的成员
	planFilename     string                   // 当前任务计划文件名
	systemRules      string                   // SYSTEM.md 全局规则

	projectTemplate *ProjectTemplate // 项目模板（可为 nil）
	teamWorkflow    string           // TEAM.md 中的流程描述（非 project-template 部分）
	Prompt          *prompt.Engine   // 提示词模板引擎

	Store          *store.Store
	currentGroupID int64 // 当前用户消息的 group_id

	cancelFunc func()
	cancelMu   sync.Mutex
}

type EventType string

const (
	EvtAgentMessage  EventType = "agent_message"
	EvtTaskAssign    EventType = "task_assign"
	EvtReview        EventType = "review"
	EvtRoomStatus    EventType = "room_status"
	EvtTasksUpdate   EventType = "tasks_update"
	EvtWorkspaceFile EventType = "workspace_file"
	EvtModeChange    EventType = "mode_change"
	EvtArtifact      EventType = "artifact"
	EvtTaskDone      EventType = "task_done"
	EvtScheduleRun   EventType = "schedule_run"
	EvtTokenUsage    EventType = "token_usage"
	EvtFileRead      EventType = "file_read"
	EvtFileWorking   EventType = "file_working"  // file-llm 开始生成文件
	EvtFileDone      EventType = "file_done"     // file-llm 文件生成完成
)

type Event struct {
	Type        EventType `json:"type"`
	RoomID      string    `json:"room_id"`
	Agent       string    `json:"agent,omitempty"`
	Role        string    `json:"role,omitempty"` // master | member | challenge
	Content     string    `json:"content,omitempty"`
	Streaming   bool      `json:"streaming,omitempty"`
	From        string    `json:"from,omitempty"`
	To          string    `json:"to,omitempty"`
	Task        string    `json:"task,omitempty"`
	Feedback    string    `json:"feedback,omitempty"`
	Status      Status    `json:"status,omitempty"`
	ActiveAgent string    `json:"active_agent,omitempty"`
	Action      string    `json:"action,omitempty"`
	Filename         string `json:"filename,omitempty"`
	Mode             string `json:"mode,omitempty"`
	Title            string `json:"title,omitempty"`
	PromptTokens     int    `json:"prompt_tokens,omitempty"`
	CompletionTokens int    `json:"completion_tokens,omitempty"`
	TotalTokens      int    `json:"total_tokens,omitempty"`
	NoStore          bool   `json:"-"` // 跳过 emit 中的自动 DB 存储（调用方已显式存储）
}

// ProjectFile 项目模板中的单个文件
type ProjectFile struct {
	Path    string // 如 "创作需求书.md"
	Owner   string // 负责的 agent 名
	Phase   int    // 阶段编号
	IsDir   bool   // 是否为目录
	Dynamic bool   // ... 标记，可动态扩展
}

// ProjectTemplate 从 TEAM.md 解析的项目模板
type ProjectTemplate struct {
	Files []ProjectFile
}

// extractTeamWorkflow 提取 TEAM.md 中除 project-template 代码块外的流程描述
func extractTeamWorkflow(body string) string {
	re := regexp.MustCompile("(?s)```project-template\\s*\\n.+?```")
	cleaned := re.ReplaceAllString(body, "")
	cleaned = strings.TrimSpace(cleaned)
	if cleaned == "" {
		return ""
	}
	return cleaned
}

// parseProjectTemplate 从 TEAM.md body 中提取 project-template 代码块并解析
func parseProjectTemplate(body string) *ProjectTemplate {
	re := regexp.MustCompile("(?s)```project-template\\s*\\n(.+?)```")
	match := re.FindStringSubmatch(body)
	if match == nil {
		return nil
	}
	block := match[1]

	lineRe := regexp.MustCompile(`[├└─│\s]+(.+?)\.md\s+@(\S+)\s*(?:phase:(\d+))?`)
	dirRe := regexp.MustCompile(`[├└─│\s]+(.+?)/\s*$`)
	dynamicRe := regexp.MustCompile(`[├└─│\s]+\.\.\.\s+@(\S+)\s*(?:phase:(\d+))?`)

	var files []ProjectFile
	for _, line := range strings.Split(block, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "workspace/") {
			continue
		}

		if m := dynamicRe.FindStringSubmatch(line); m != nil {
			phase := 0
			if m[2] != "" {
				phase, _ = strconv.Atoi(m[2])
			}
			files = append(files, ProjectFile{
				Path: "...", Owner: m[1], Phase: phase, Dynamic: true,
			})
			continue
		}

		if m := dirRe.FindStringSubmatch(line); m != nil {
			files = append(files, ProjectFile{
				Path: m[1] + "/", IsDir: true,
			})
			continue
		}

		if m := lineRe.FindStringSubmatch(line); m != nil {
			phase := 0
			if m[3] != "" {
				phase, _ = strconv.Atoi(m[3])
			}
			files = append(files, ProjectFile{
				Path: strings.TrimSpace(m[1]) + ".md", Owner: m[2], Phase: phase,
			})
		}
	}

	if len(files) == 0 {
		return nil
	}
	return &ProjectTemplate{Files: files}
}

// LoadOption 用于 room.Load 的可选参数
type LoadOption func(*loadOptions)

type loadOptions struct {
	store *store.Store
}

// WithStore 在加载时传入 store，用于从 DB 读取 agent 配置
func WithStore(s *store.Store) LoadOption {
	return func(o *loadOptions) {
		o.store = s
	}
}

type BoardEntry struct {
	Author  string
	Content string
	Type    string // "draft" | "challenge"
}

type SharedBoard struct {
	mu      sync.RWMutex
	entries []BoardEntry
}

func (b *SharedBoard) Add(author, content, typ string) {
	b.mu.Lock()
	defer b.mu.Unlock()
	b.entries = append(b.entries, BoardEntry{Author: author, Content: content, Type: typ})
}

func (b *SharedBoard) ToContext() string {
	b.mu.RLock()
	defer b.mu.RUnlock()
	if len(b.entries) == 0 {
		return ""
	}
	var sb strings.Builder
	sb.WriteString("<team_board>\n")
	for _, e := range b.entries {
		fmt.Fprintf(&sb, "  <entry type=\"%s\" author=\"%s\">\n%s\n  </entry>\n", e.Type, e.Author, e.Content)
	}
	sb.WriteString("</team_board>")
	return sb.String()
}
