package subsession

import (
	"context"
	"fmt"
	"git.yeij.top/AskaEth/Cyrene/pkg/logger"
	"regexp"
	"strings"
	"time"

	"git.yeij.top/AskaEth/Cyrene/ai-core/internal/model"
)

// ReviewProvider 最终审查子会话提供者
// 职责：解析编排器输出文本，将其拆分为带类型的消息（action/chat），
// 分割长消息为短消息，输出格式化的消息列表供前端渲染。
type ReviewProvider struct{}

// NewReviewProvider 创建审查子会话提供者
func NewReviewProvider() *ReviewProvider {
	return &ReviewProvider{}
}

func (p *ReviewProvider) Type() model.SubSessionType {
	return model.SubSessionReview
}

func (p *ReviewProvider) CanHandle(_ context.Context, _ *model.IntentResult, _ string) bool {
	// 审查提供者始终可用于处理综合后的文本
	return true
}

func (p *ReviewProvider) Priority() int {
	return 1 // 最高优先级，最先处理输出
}

func (p *ReviewProvider) Timeout() time.Duration {
	return 5 * time.Second // 审查很快，无需长时间
}

func (p *ReviewProvider) CreateContext(_ context.Context, params CreateContextParams) ([]model.LLMMessage, error) {
	// Review 不依赖 LLM 上下文，直接处理文本
	return []model.LLMMessage{
		{Role: model.RoleSystem, Content: "最终审查子会话 - 格式化输出"},
	}, nil
}

func (p *ReviewProvider) Execute(_ context.Context, subCtx []model.LLMMessage) (*model.SubSessionResult, error) {
	// 提取待审查的文本（从最后一条 user 消息中获取，由 Orchestrator 注入）
	text := ""
	for i := len(subCtx) - 1; i >= 0; i-- {
		if subCtx[i].Role == model.RoleUser {
			text = subCtx[i].Content
			break
		}
	}

	if text == "" {
		return &model.SubSessionResult{
			Type:    model.SubSessionReview,
			Summary: "（无需审查，文本为空）",
		}, nil
	}

	reviewMessages := parseReviewText(text)

	logger.Printf("[review-provider] 审查完成: 输入 %d 字符 → %d 条消息",
		len([]rune(text)), len(reviewMessages))

	// 构建摘要
	var parts []string
	for _, rm := range reviewMessages {
		typeLabel := "💬"
		if rm.Type == model.ReviewMessageAction {
			typeLabel = "⚡"
		}
		runes := []rune(rm.Content)
		preview := rm.Content
		if len(runes) > 30 {
			preview = string(runes[:30]) + "..."
		}
		parts = append(parts, fmt.Sprintf("%s %s", typeLabel, preview))
	}

	result := &model.SubSessionResult{
		Type:       model.SubSessionReview,
		Summary:    fmt.Sprintf("审查完成: %d 条消息", len(reviewMessages)),
		Details:    strings.Join(parts, "\n"),
		Confidence: 0.95,
		Metadata: map[string]any{
			"review_messages": reviewMessages,
		},
	}

	return result, nil
}

// parseReviewText 解析原始文本，提取带类型的消息
// 规则：
// - （xxx）或 (xxx) → action 类型消息
// - "xxx" 或 "xxx" → chat 类型消息（提取引号内容）
// - 普通文本 → chat 类型消息
// - 长消息 (>80 字符) → 按句子边界拆分为多条
func parseReviewText(text string) []model.ReviewMessage {
	if text == "" {
		return nil
	}

	var messages []model.ReviewMessage

	// 模式1: 匹配括号内容作为 action — （...）或 (...)
	actionPattern := regexp.MustCompile(`[（(]([^）)]+)[）)]`)
	// 模式2: 匹配引号内容 — "..."
	quotePattern := regexp.MustCompile(`[""]([^""]+)[""]`)
	// 模式3: 匹配方括号动作 — 【...】
	bracketPattern := regexp.MustCompile(`【([^】]+)】`)

	// 先收集所有匹配的位置
	type matchRange struct {
		start int
		end   int
		typ   model.ReviewMessageType
		text  string
	}

	var matches []matchRange

	// 收集括号动作
	for _, m := range actionPattern.FindAllStringSubmatchIndex(text, -1) {
		matches = append(matches, matchRange{
			start: m[0],
			end:   m[1],
			typ:   model.ReviewMessageAction,
			text:  text[m[2]:m[3]], // 括号内文本
		})
	}

	// 收集方括号动作
	for _, m := range bracketPattern.FindAllStringSubmatchIndex(text, -1) {
		matches = append(matches, matchRange{
			start: m[0],
			end:   m[1],
			typ:   model.ReviewMessageAction,
			text:  text[m[2]:m[3]],
		})
	}

	// 收集引号内容
	for _, m := range quotePattern.FindAllStringSubmatchIndex(text, -1) {
		matches = append(matches, matchRange{
			start: m[0],
			end:   m[1],
			typ:   model.ReviewMessageChat,
			text:  text[m[2]:m[3]],
		})
	}

	// 如果没有匹配，整个文本作为 chat
	if len(matches) == 0 {
		return splitLongMessage(model.ReviewMessageChat, strings.TrimSpace(text))
	}

	// 简单排序（按出现顺序）
	for i := 0; i < len(matches); i++ {
		for j := i + 1; j < len(matches); j++ {
			if matches[i].start > matches[j].start {
				matches[i], matches[j] = matches[j], matches[i]
			}
		}
	}

	// 处理匹配之间的普通文本
	pos := 0
	for _, m := range matches {
		// 匹配前的普通文本
		if m.start > pos {
			plainText := strings.TrimSpace(text[pos:m.start])
			if plainText != "" {
				messages = append(messages, splitLongMessage(model.ReviewMessageChat, plainText)...)
			}
		}
		// 添加匹配项
		messages = append(messages, model.ReviewMessage{
			Type:    m.typ,
			Content: strings.TrimSpace(m.text),
		})
		pos = m.end
	}

	// 剩余文本
	if pos < len(text) {
		remaining := strings.TrimSpace(text[pos:])
		if remaining != "" {
			messages = append(messages, splitLongMessage(model.ReviewMessageChat, remaining)...)
		}
	}

	if len(messages) == 0 {
		messages = append(messages, model.ReviewMessage{
			Type:    model.ReviewMessageChat,
			Content: strings.TrimSpace(text),
		})
	}

	return messages
}

// splitLongMessage 将长消息按句子边界拆分为多条短消息
func splitLongMessage(msgType model.ReviewMessageType, text string) []model.ReviewMessage {
	const maxLen = 80 // 最大字符数（按 rune 计数）

	runes := []rune(text)
	if len(runes) <= maxLen {
		return []model.ReviewMessage{{Type: msgType, Content: text}}
	}

	var messages []model.ReviewMessage
	start := 0

	for start < len(runes) {
		end := start + maxLen
		if end > len(runes) {
			end = len(runes)
		}

		// 尝试在句子边界处分割
		chunk := string(runes[start:end])

		// 如果这不是最后一个 chunk，在句子边界处切割
		if end < len(runes) {
			// 从后往前找最近的句子分隔符
			lastSentenceBreak := -1
			for i := len(chunk) - 1; i >= len(chunk)/2; i-- {
				ch := runes[start+i]
				if ch == '。' || ch == '！' || ch == '？' || ch == '.' || ch == '!' || ch == '?' || ch == '；' || ch == ';' || ch == '\n' {
					lastSentenceBreak = i
					break
				}
			}
			// 如果没有找到句子分隔符，找逗号或空格
			if lastSentenceBreak < 0 {
				for i := len(chunk) - 1; i >= len(chunk)/2; i-- {
					ch := runes[start+i]
					if ch == '，' || ch == ',' || ch == ' ' || ch == '　' {
						lastSentenceBreak = i
						break
					}
				}
			}

			if lastSentenceBreak > 0 {
				chunk = string(runes[start : start+lastSentenceBreak+1])
				end = start + lastSentenceBreak + 1
			}
		}

		chunk = strings.TrimSpace(chunk)
		if chunk != "" {
			messages = append(messages, model.ReviewMessage{
				Type:    msgType,
				Content: chunk,
			})
		}

		start = end
	}

	if len(messages) == 0 {
		messages = append(messages, model.ReviewMessage{
			Type:    msgType,
			Content: text,
		})
	}

	return messages
}
