// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

// Package habits provides MCP tools for habit tracking in Lunatask.
package habits

import (
	"context"
	"fmt"
	"strings"

	"git.secluded.site/go-lunatask"
	"github.com/mark3labs/mcp-go/mcp"

	"git.sr.ht/~amolith/lunatask-mcp-server/tools/shared"
)

// Handler handles habit-related MCP tool calls.
type Handler struct {
	accessToken string
	habits      []shared.HabitProvider
}

// NewHandler creates a new habits Handler.
func NewHandler(accessToken string, habits []shared.HabitProvider) *Handler {
	return &Handler{
		accessToken: accessToken,
		habits:      habits,
	}
}

// HandleList handles the list_habits_and_activities tool call.
func (h *Handler) HandleList(
	_ context.Context,
	_ mcp.CallToolRequest,
) (*mcp.CallToolResult, error) {
	var builder strings.Builder

	for _, habit := range h.habits {
		fmt.Fprintf(&builder, "- %s: %s\n", habit.GetName(), habit.GetID())
	}

	return &mcp.CallToolResult{
		Content: []mcp.Content{
			mcp.TextContent{
				Type: "text",
				Text: builder.String(),
			},
		},
	}, nil
}

// HandleTrack handles the track_habit_activity tool call.
//
//nolint:wrapcheck // ReportError returns nil for error
func (h *Handler) HandleTrack(
	ctx context.Context,
	request mcp.CallToolRequest,
) (*mcp.CallToolResult, error) {
	habitID, ok := request.Params.Arguments["habit_id"].(string)
	if !ok || habitID == "" {
		return shared.ReportError("Missing or invalid required argument: habit_id")
	}

	performedOnStr, ok := request.Params.Arguments["performed_on"].(string)
	if !ok || performedOnStr == "" {
		return shared.ReportError("Missing or invalid required argument: performed_on")
	}

	performedOn, err := lunatask.ParseDate(performedOnStr)
	if err != nil {
		return shared.ReportError(fmt.Sprintf(
			"Invalid format for performed_on: '%s'. Must be YYYY-MM-DD.",
			performedOnStr,
		))
	}

	client := lunatask.NewClient(h.accessToken)
	habitRequest := &lunatask.TrackHabitActivityRequest{
		PerformedOn: performedOn,
	}

	resp, err := client.TrackHabitActivity(ctx, habitID, habitRequest)
	if err != nil {
		return shared.ReportError(fmt.Sprintf("Failed to track habit activity: %v", err))
	}

	return &mcp.CallToolResult{
		Content: []mcp.Content{
			mcp.TextContent{
				Type: "text",
				Text: fmt.Sprintf(
					"Habit activity tracked successfully. Status: %s, Message: %s",
					resp.Status,
					resp.Message,
				),
			},
		},
	}, nil
}
