package tools

import (
	"context"
	"strings"

	"github.com/google/uuid"
	"github.com/modelcontextprotocol/go-sdk/mcp"

	"git.warky.dev/wdevs/amcs/internal/ai"
	"git.warky.dev/wdevs/amcs/internal/config"
	"git.warky.dev/wdevs/amcs/internal/session"
	"git.warky.dev/wdevs/amcs/internal/store"
)

type SummarizeTool struct {
	store      *store.DB
	embeddings *ai.EmbeddingRunner
	metadata   *ai.MetadataRunner
	search     config.SearchConfig
	sessions   *session.ActiveProjects
}

type SummarizeInput struct {
	Query   string `json:"query,omitempty" jsonschema:"optional semantic focus for the summary"`
	Project string `json:"project,omitempty" jsonschema:"optional project name or id; falls back to the active session project"`
	Days    int    `json:"days,omitempty" jsonschema:"only include thoughts from the last N days when query is omitted"`
	Limit   int    `json:"limit,omitempty" jsonschema:"maximum number of thoughts to summarize"`
}

type SummarizeOutput struct {
	Summary string `json:"summary"`
	Count   int    `json:"count"`
}

func NewSummarizeTool(db *store.DB, embeddings *ai.EmbeddingRunner, metadata *ai.MetadataRunner, search config.SearchConfig, sessions *session.ActiveProjects) *SummarizeTool {
	return &SummarizeTool{store: db, embeddings: embeddings, metadata: metadata, search: search, sessions: sessions}
}

func (t *SummarizeTool) Handle(ctx context.Context, req *mcp.CallToolRequest, in SummarizeInput) (*mcp.CallToolResult, SummarizeOutput, error) {
	project, err := resolveProject(ctx, t.store, t.sessions, req, in.Project, false)
	if err != nil {
		return nil, SummarizeOutput{}, err
	}

	limit := normalizeLimit(in.Limit, t.search)
	query := strings.TrimSpace(in.Query)
	lines := make([]string, 0, limit)
	count := 0

	if query != "" {
		var projectID *uuid.UUID
		if project != nil {
			projectID = &project.ID
		}
		results, err := semanticSearch(ctx, t.store, t.embeddings, t.search, query, limit, t.search.DefaultThreshold, projectID, nil)
		if err != nil {
			return nil, SummarizeOutput{}, err
		}
		for i, result := range results {
			lines = append(lines, thoughtContextLine(i, result.Content, result.Metadata, result.Similarity))
		}
		count = len(results)
	} else {
		var projectID *uuid.UUID
		if project != nil {
			projectID = &project.ID
		}
		thoughts, err := t.store.RecentThoughts(ctx, projectID, limit, in.Days)
		if err != nil {
			return nil, SummarizeOutput{}, err
		}
		for i, thought := range thoughts {
			lines = append(lines, thoughtContextLine(i, thought.Content, thought.Metadata, 0))
		}
		count = len(thoughts)
	}

	userPrompt := formatContextBlock("Summarize the following thoughts into concise prose with themes, action items, and notable people.", lines)
	systemPrompt := "You summarize note collections. Be concise, concrete, and structured in plain prose."
	summary, err := t.metadata.Summarize(ctx, systemPrompt, userPrompt)
	if err != nil {
		return nil, SummarizeOutput{}, err
	}
	if project != nil {
		_ = t.store.TouchProject(ctx, project.ID)
	}

	return nil, SummarizeOutput{Summary: summary, Count: count}, nil
}
