package tools

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"chat-switchboard/store"
)

// ── Late Registration ────────────────────────

func RegisterConversationSearch(stores store.Stores) {
	Register(&conversationSearchTool{stores: stores})
}

// ═══════════════════════════════════════════
// conversation_search
// ═══════════════════════════════════════════

type conversationSearchTool struct {
	BaseTool
	stores store.Stores
}

func (t *conversationSearchTool) Definition() ToolDef {
	return ToolDef{
		Name:        "conversation_search",
		DisplayName: "Search Chat",
		Category:    "context",
		Description: "Search earlier messages in this conversation by keyword. " +
			"Useful when the conversation is long or has been summarized and " +
			"you need to find specific details from earlier discussion. " +
			"Returns matching message excerpts with timestamps.",
		Parameters: JSONSchema(map[string]interface{}{
			"query": Prop("string", "Search keywords — use terms likely to appear in the messages"),
			"max_results": map[string]interface{}{
				"type":        "integer",
				"description": "Maximum results to return (1-20, default 5)",
			},
			"role_filter": PropEnum(
				"Filter by message role (default: all)",
				"all", "user", "assistant",
			),
		}, []string{"query"}),
	}
}

func (t *conversationSearchTool) Execute(ctx context.Context, execCtx ExecutionContext, argsJSON string) (string, error) {
	var args struct {
		Query      string `json:"query"`
		MaxResults int    `json:"max_results"`
		RoleFilter string `json:"role_filter"`
	}
	if err := json.Unmarshal([]byte(argsJSON), &args); err != nil {
		return "", fmt.Errorf("invalid arguments: %w", err)
	}

	if args.Query == "" {
		return "", fmt.Errorf("query is required")
	}
	if args.MaxResults <= 0 || args.MaxResults > 20 {
		args.MaxResults = 5
	}

	storeResults, err := t.stores.Messages.SearchInChannel(ctx, execCtx.ChannelID, args.Query, args.RoleFilter, args.MaxResults)
	if err != nil {
		return "", fmt.Errorf("search failed: %w", err)
	}

	type searchResult struct {
		MessageID string  `json:"message_id"`
		Role      string  `json:"role"`
		Excerpt   string  `json:"excerpt"`
		Rank      float64 `json:"rank"`
		Timestamp string  `json:"timestamp"`
	}

	results := make([]searchResult, 0, len(storeResults))
	for _, sr := range storeResults {
		results = append(results, searchResult{
			MessageID: sr.MessageID,
			Role:      sr.Role,
			Excerpt:   sr.Excerpt,
			Rank:      sr.Rank,
			Timestamp: sr.Timestamp.Format(time.RFC3339),
		})
	}

	log.Printf("🔍 conversation_search: %q → %d results in channel %s",
		args.Query, len(results), execCtx.ChannelID)

	out, _ := json.Marshal(map[string]interface{}{
		"results":    results,
		"query":      args.Query,
		"total":      len(results),
		"channel_id": execCtx.ChannelID,
	})
	return string(out), nil
}
