package routing

import "strings"

const (
	MessageTypeOwnerQuote               = "owner_quote"
	OwnerQuoteHeader                    = "Owner quote"
	OwnerQuoteSourceRefsSectionHeader   = "Source message refs:"
	OwnerQuoteSourceRefLinePrefix       = "- source_message_id="
	OwnerQuoteInstructionSectionHeader  = "Body:"
	OwnerQuoteFallbackInstructionHeader = "Instruction:"
	OwnerQuoteQuotedMessagesHeader      = "Quoted messages:"
)

// MentionRoutingContent returns the content subset eligible for live mention
// routing. Structured owner_quote messages route over the final owner-edited
// quote body while stripping machine metadata.
func MentionRoutingContent(messageType, content string) string {
	if strings.TrimSpace(messageType) == MessageTypeOwnerQuote {
		if len(ParseOwnerQuoteSourceMessageIDs(content)) > 0 {
			return ExtractOwnerQuoteMentionContent(content)
		}
		return ""
	}
	return content
}

func ParseOwnerQuoteSourceMessageIDs(content string) []string {
	lines := strings.Split(strings.ReplaceAll(content, "\r\n", "\n"), "\n")
	ids := make([]string, 0)
	seen := make(map[string]struct{})
	inSourceRefsSection := false

	for _, rawLine := range lines {
		line := strings.TrimSpace(rawLine)
		if !inSourceRefsSection {
			if line == OwnerQuoteSourceRefsSectionHeader {
				inSourceRefsSection = true
			}
			continue
		}
		if line == "" {
			continue
		}
		if !strings.HasPrefix(line, OwnerQuoteSourceRefLinePrefix) {
			break
		}
		sourceMessageID := strings.TrimSpace(strings.TrimPrefix(line, OwnerQuoteSourceRefLinePrefix))
		if sourceMessageID == "" {
			continue
		}
		if _, ok := seen[sourceMessageID]; ok {
			continue
		}
		seen[sourceMessageID] = struct{}{}
		ids = append(ids, sourceMessageID)
	}

	return ids
}

// ExtractOwnerQuoteMentionContent returns the instruction and quoted message
// bodies from an owner_quote raw draft, suitable for mention token parsing.
// It strips structural metadata lines (author=, message_id=, created_at=,
// source_message_id=, section headers) so metadata @mentions are not treated as
// delivery targets.
func ExtractOwnerQuoteMentionContent(content string) string {
	normalized := strings.ReplaceAll(content, "\r\n", "\n")
	lines := strings.Split(normalized, "\n")

	var parts []string
	inQuotedSection := false
	skippingSourceRefs := false
	skippingAttachmentBlock := false

	for _, line := range lines {
		trimmed := strings.TrimSpace(line)

		if skippingAttachmentBlock {
			if trimmed == "" || strings.HasPrefix(trimmed, "- ") {
				continue
			}
			skippingAttachmentBlock = false
		}

		if skippingSourceRefs {
			if trimmed == "" || strings.HasPrefix(trimmed, OwnerQuoteSourceRefLinePrefix) {
				continue
			}
			skippingSourceRefs = false
		}

		if trimmed == OwnerQuoteSourceRefsSectionHeader {
			skippingSourceRefs = true
			continue
		}

		if trimmed == OwnerQuoteInstructionSectionHeader || trimmed == OwnerQuoteFallbackInstructionHeader {
			continue
		}
		if trimmed == OwnerQuoteHeader {
			continue
		}
		if trimmed == OwnerQuoteQuotedMessagesHeader {
			inQuotedSection = true
			continue
		}

		if inQuotedSection && isOwnerQuoteSourceHeaderLine(trimmed) {
			continue
		}
		if inQuotedSection && trimmed == "Attachments:" {
			skippingAttachmentBlock = true
			continue
		}

		parts = append(parts, line)
	}

	return strings.TrimSpace(strings.Join(parts, "\n"))
}

func isOwnerQuoteSourceHeaderLine(line string) bool {
	if len(line) < len("[] author=@ message_id= created_at=") || line[0] != '[' {
		return false
	}
	closeBracket := strings.IndexByte(line, ']')
	if closeBracket <= 1 {
		return false
	}
	for _, r := range line[1:closeBracket] {
		if r < '0' || r > '9' {
			return false
		}
	}
	rest := strings.TrimSpace(line[closeBracket+1:])
	if !strings.HasPrefix(rest, "author=@") {
		return false
	}
	messageIDIndex := strings.LastIndex(rest, " message_id=")
	createdAtIndex := strings.LastIndex(rest, " created_at=")
	return messageIDIndex > len("author=@") &&
		createdAtIndex > messageIDIndex+len(" message_id=") &&
		createdAtIndex+len(" created_at=") < len(rest)
}

func ExtractOwnerQuoteInstruction(content string) string {
	normalized := strings.ReplaceAll(content, "\r\n", "\n")

	var header string
	var start int
	for _, candidate := range []string{OwnerQuoteInstructionSectionHeader, OwnerQuoteFallbackInstructionHeader} {
		idx := strings.Index(normalized, candidate+"\n")
		if idx >= 0 {
			header = candidate
			start = idx
			break
		}
	}
	if header == "" {
		return ""
	}

	afterInstruction := normalized[start+len(header)+1:]
	sourceRefsStart := strings.Index(afterInstruction, "\n"+OwnerQuoteSourceRefsSectionHeader)
	if sourceRefsStart < 0 {
		return strings.TrimSpace(afterInstruction)
	}

	return strings.TrimSpace(afterInstruction[:sourceRefsStart])
}
