package mcp

import (
	"context"
	"fmt"
	"strings"

	"github.com/agentuity/cli/internal/project"
	mcp_golang "github.com/agentuity/mcp-golang/v2"
)

type EnvSetArguments struct {
	Key       string `json:"key" jsonschema:"required,description=The name of the environment variable or secret to set"`
	Value     string `json:"value" jsonschema:"required,description=The value to set the environment variable or secret to set"`
	IsSecret  bool   `json:"isSecret" jsonschema:"required,description=Set to true if the environment variable is a secret or looks at all like a secret, api key, password, etc"`
	Directory string `json:"directory" jsonschema:"required,description=The directory where the project is located"`
}

type EnvDeleteArguments struct {
	Keys      []string `json:"keys" jsonschema:"required,description=The names of the environment variables or secrets to delete"`
	Directory string   `json:"directory" jsonschema:"required,description=The directory where the project is located"`
}

type EnvListArguments struct {
	Directory string `json:"directory" jsonschema:"required,description=The directory where the project is located"`
}

func init() {
	register(func(c MCPContext) error {
		return c.Server.RegisterTool("set_project_environment", "this is a tool for setting the environment variable or secret for the current agentuity project", func(ctx context.Context, args EnvSetArguments) (*mcp_golang.ToolResponse, error) {
			if resp := ensureLoggedIn(&c); resp != nil {
				return resp, nil
			}
			if args.Directory != "" {
				c.ProjectDir = args.Directory
			}
			if resp := ensureProject(&c); resp != nil {
				return resp, nil
			}
			if strings.HasPrefix(args.Key, "AGENTUITY_") {
				return mcp_golang.NewToolResponse(mcp_golang.NewTextContent("You cannot set a project environment variable that starts with AGENTUITY_")), nil
			}
			var err error
			if args.IsSecret {
				_, err = project.SetProjectEnv(ctx, c.Logger, c.APIURL, c.APIKey, c.Project.ProjectId, map[string]string{}, map[string]string{args.Key: args.Value})
			} else {
				_, err = project.SetProjectEnv(ctx, c.Logger, c.APIURL, c.APIKey, c.Project.ProjectId, map[string]string{args.Key: args.Value}, map[string]string{})
			}
			if err != nil {
				return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("Error setting environment variable: %s", err))), nil
			}
			project.SaveEnvValue(ctx, c.Logger, c.ProjectDir, map[string]string{args.Key: args.Value})
			if args.IsSecret {
				return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("%s was set as a secret", args.Key))), nil
			}
			return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("%s was set", args.Key))), nil
		})
	})

	register(func(c MCPContext) error {
		return c.Server.RegisterTool("list_project_environment", "this is a tool for showing the environment variable or secrets configured for the current agentuity project", func(ctx context.Context, args EnvListArguments) (*mcp_golang.ToolResponse, error) {
			if resp := ensureLoggedIn(&c); resp != nil {
				return resp, nil
			}
			if args.Directory != "" {
				c.ProjectDir = args.Directory
			}
			if resp := ensureProject(&c); resp != nil {
				return resp, nil
			}
			output, err := execCommand(ctx, c.ProjectDir, "env", "list", "--format", "json")
			return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(output)), err
		})
	})

	register(func(c MCPContext) error {
		return c.Server.RegisterTool("delete_project_environment", "this is a tool for deleting one or more environment variables or secrets configured for the current agentuity project", func(ctx context.Context, args EnvDeleteArguments) (*mcp_golang.ToolResponse, error) {
			if resp := ensureLoggedIn(&c); resp != nil {
				return resp, nil
			}
			if args.Directory != "" {
				c.ProjectDir = args.Directory
			}
			if resp := ensureProject(&c); resp != nil {
				return resp, nil
			}
			if err := project.DeleteProjectEnv(ctx, c.Logger, c.APIURL, c.APIKey, c.Project.ProjectId, args.Keys, args.Keys); err != nil {
				return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("Error deleting environment variable: %s", err))), nil
			}
			if err := project.RemoveEnvValues(ctx, c.Logger, c.ProjectDir, args.Keys...); err != nil {
				return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("Error deleting environment variable from .env file: %s", err))), nil
			}
			return mcp_golang.NewToolResponse(mcp_golang.NewTextContent("Environment variables and secrets deleted")), nil
		})
	})
}
