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

// Package areas provides the MCP resource handler for Lunatask areas and goals.
package areas

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

	"git.secluded.site/lune/internal/mcp/shared"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

// ResourceURI is the URI for the areas resource.
const ResourceURI = "lunatask://areas"

// ResourceDescription describes the areas resource for LLMs.
const ResourceDescription = `Lists all configured Lunatask areas and their goals.

Each area represents a life domain (e.g., Work, Personal, Health) and contains:
- id: UUID to use when creating tasks in this area
- name: Human-readable area name
- key: Short alias for CLI usage
- goals: List of goals within the area, each with id, name, and key

Use this resource to discover valid area and goal IDs before creating or updating tasks.`

// Handler handles area resource requests.
type Handler struct {
	areas []shared.AreaProvider
}

// NewHandler creates a new areas resource handler.
func NewHandler(areas []shared.AreaProvider) *Handler {
	return &Handler{areas: areas}
}

// areaInfo represents an area in the resource response.
type areaInfo struct {
	ID    string     `json:"id"`
	Name  string     `json:"name"`
	Key   string     `json:"key"`
	Goals []goalInfo `json:"goals"`
}

// goalInfo represents a goal in the resource response.
type goalInfo struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Key  string `json:"key"`
}

// HandleRead returns the configured areas and goals.
func (h *Handler) HandleRead(
	_ context.Context,
	_ *mcp.ReadResourceRequest,
) (*mcp.ReadResourceResult, error) {
	areasInfo := make([]areaInfo, 0, len(h.areas))

	for _, area := range h.areas {
		goals := make([]goalInfo, 0, len(area.Goals))
		for _, g := range area.Goals {
			goals = append(goals, goalInfo{
				ID:   g.ID,
				Name: g.Name,
				Key:  g.Key,
			})
		}

		areasInfo = append(areasInfo, areaInfo{
			ID:    area.ID,
			Name:  area.Name,
			Key:   area.Key,
			Goals: goals,
		})
	}

	data, err := json.MarshalIndent(areasInfo, "", "  ")
	if err != nil {
		return nil, fmt.Errorf("marshaling areas: %w", err)
	}

	return &mcp.ReadResourceResult{
		Contents: []*mcp.ResourceContents{{
			URI:      ResourceURI,
			MIMEType: "application/json",
			Text:     string(data),
		}},
	}, nil
}
