package matrix

import (
	"context"
	"fmt"

	"github.com/enmanuel/agents/internal/config"
	"github.com/enmanuel/agents/tools"
)

// MatrixSender is the interface for sending Matrix messages.
// Satisfied by shell/matrix.Client.
type MatrixSender interface {
	SendText(ctx context.Context, roomID, text string) error
	SendMarkdown(ctx context.Context, roomID, markdown string) error
}

// NewMatrixSend creates a matrix_send tool that sends a message to a Matrix room.
// If AllowedRooms is configured, only those room IDs can be targeted.
func NewMatrixSend(sender MatrixSender, cfg config.MatrixToolCfg) tools.Tool {
	return tools.Tool{
		Def: tools.Def{
			Name:        "matrix_send",
			Description: "Send a text message to a Matrix room.",
			Parameters: []tools.Param{
				{Name: "room_id", Type: "string", Description: "The Matrix room ID to send to", Required: true},
				{Name: "message", Type: "string", Description: "The text message to send", Required: true},
			},
		},
		Exec: func(ctx context.Context, args map[string]any) tools.Result {
			roomID := tools.GetString(args, "room_id")
			message := tools.GetString(args, "message")
			if roomID == "" || message == "" {
				return tools.Result{Err: fmt.Errorf("matrix_send: room_id and message are required")}
			}

			if err := validateRoom(roomID, cfg.AllowedRooms); err != nil {
				return tools.Result{Err: err}
			}

			if err := sender.SendMarkdown(ctx, roomID, message); err != nil {
				return tools.Result{Err: fmt.Errorf("matrix_send: %w", err)}
			}

			return tools.Result{Output: fmt.Sprintf("message sent to %s", roomID)}
		},
	}
}

// validateRoom checks that roomID is in the allowed list.
// If allowedRooms is empty, all rooms are allowed.
func validateRoom(roomID string, allowedRooms []string) error {
	if len(allowedRooms) == 0 {
		return nil
	}
	for _, r := range allowedRooms {
		if roomID == r {
			return nil
		}
	}
	return fmt.Errorf("matrix_send: room %q not in allowed rooms list", roomID)
}
