package main

import (
	"context"
	"encoding/json"
	"errors"
	"net/http"
	"os"
	"strings"

	"fn-registry/functions/infra"
)

// mcpHTTPHandler builds the http.Handler that serves the MCP Streamable HTTP
// transport for remote Claude clients. Bearer-auth backed by the mcp_tokens
// table; tool dispatch reuses executeToolAs() so per-user tools (add_comment,
// delete_comment) can infer the actor from the authenticated token.
func mcpHTTPHandler(db *DB) http.Handler {
	auth := func(r *http.Request) (context.Context, error) {
		header := r.Header.Get("Authorization")
		token := strings.TrimSpace(strings.TrimPrefix(header, "Bearer "))
		if token == "" || token == header {
			return nil, errors.New("missing bearer token")
		}
		userID, err := db.LookupMCPToken(token)
		if err != nil {
			return nil, err
		}
		if userID == "" {
			return nil, errors.New("invalid or revoked token")
		}
		return context.WithValue(r.Context(), userCtxKey, userID), nil
	}

	handler := func(ctx context.Context, name string, input json.RawMessage) (any, bool, error) {
		body := input
		if len(body) == 0 {
			body = json.RawMessage(`{}`)
		}
		actor, _ := infra.UserIDFromContext(ctx, userCtxKey)
		res := executeToolAs(db, name, body, actor)
		if !res.OK {
			return res.Error, true, nil
		}
		return res.Result, false, nil
	}

	return infra.MCPHTTPHandler(infra.MCPHTTPOpts{
		Name:    "kanban",
		Version: Version,
		Tools:   mcpToolDefs(),
		Handler: handler,
		Auth:    auth,
		Logger:  os.Stderr,
	})
}
