// Package message provides pure parsing and formatting for Matrix messages.
package message

import (
	"strings"

	"github.com/enmanuel/agents/pkg/decision"
)

// ParseOptions configures how messages are parsed.
type ParseOptions struct {
	CommandPrefix    string   // e.g. "!"
	BotUserID        string   // for mention detection, e.g. "@bot:server"
	MentionedUserIDs []string // pre-extracted from m.mentions event field (modern Matrix spec)
}

// Parse converts a raw Matrix message body into a structured MessageContext. Pure.
func Parse(body, senderID, roomID string, powerLevel int, isDM bool, opts ParseOptions) decision.MessageContext {
	ctx := decision.MessageContext{
		SenderID:    senderID,
		RoomID:      roomID,
		Content:     body,
		PowerLevel:  powerLevel,
		IsDirectMsg: isDM,
	}

	// Detect mention: check m.mentions list first (modern Matrix spec).
	if opts.BotUserID != "" {
		for _, uid := range opts.MentionedUserIDs {
			if uid == opts.BotUserID {
				ctx.IsMention = true
				break
			}
		}
		// Fallback: check if full user ID appears in the plain text body.
		if !ctx.IsMention && strings.Contains(body, opts.BotUserID) {
			ctx.IsMention = true
		}
	}

	// Parse command.
	// When CommandPrefix is non-empty (e.g. "!"), only messages starting with that
	// prefix are treated as commands.
	// When CommandPrefix is empty, every message is a potential command: the first
	// token is the command name. If it starts with "!", the "!" is stripped for
	// backward compatibility (so both "help" and "!help" work the same).
	switch {
	case opts.CommandPrefix != "":
		// Standard mode: require prefix
		if strings.HasPrefix(body, opts.CommandPrefix) {
			parts := strings.Fields(strings.TrimPrefix(body, opts.CommandPrefix))
			if len(parts) > 0 {
				ctx.Command = strings.ToLower(parts[0])
				ctx.Args = parts[1:]
			}
		}
	case opts.CommandPrefix == "":
		// No-prefix mode: treat first token as command
		parts := strings.Fields(body)
		if len(parts) > 0 {
			cmd := parts[0]
			// Strip leading "!" for backward compatibility
			cmd = strings.TrimPrefix(cmd, "!")
			if cmd != "" {
				ctx.Command = strings.ToLower(cmd)
				ctx.Args = parts[1:]
			}
		}
	}

	return ctx
}
