// 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 = `Configured Lunatask areas and goals.

Each area contains: id, name, key, workflow info, and goals.
Use area key or id in resource templates like lunatask://area/{area}/today.`

// 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"`
	Workflow            string     `json:"workflow"`
	WorkflowDescription string     `json:"workflow_description"`
	ValidStatuses       []string   `json:"valid_statuses"`
	UsesMotivation      bool       `json:"uses_motivation"`
	UsesEisenhower      bool       `json:"uses_eisenhower"`
	UsesScheduling      bool       `json:"uses_scheduling"`
	UsesPriority        bool       `json:"uses_priority"`
	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,
			})
		}

		validStatuses := make([]string, 0, len(area.Workflow.ValidStatuses()))
		for _, s := range area.Workflow.ValidStatuses() {
			validStatuses = append(validStatuses, string(s))
		}

		areasInfo = append(areasInfo, areaInfo{
			ID:                  area.ID,
			Name:                area.Name,
			Key:                 area.Key,
			Workflow:            string(area.Workflow),
			WorkflowDescription: area.Workflow.Description(),
			ValidStatuses:       validStatuses,
			UsesMotivation:      area.Workflow.UsesMotivation(),
			UsesEisenhower:      area.Workflow.UsesEisenhower(),
			UsesScheduling:      area.Workflow.UsesScheduling(),
			UsesPriority:        area.Workflow.UsesPriority(),
			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
}
