package tools

import (
	"context"
	"fmt"

	"github.com/ClareAI/astra-insight-mcp/internal/gateway"
	"github.com/ClareAI/astra-insight-mcp/internal/mcp"
)

func parseStringSlice(v interface{}) []string {
	if v == nil {
		return nil
	}
	arr, ok := v.([]interface{})
	if !ok {
		return nil
	}
	var out []string
	for _, e := range arr {
		if s, ok := e.(string); ok {
			out = append(out, s)
		}
	}
	return out
}

func registerListWebhooks(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "list_webhooks",
		Description: "List registered webhooks — URLs, subscribed events, and active status.",
		InputSchema: mcp.InputSchema{
			Type:       "object",
			Properties: map[string]mcp.Property{},
			Required:   []string{},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		if apiKey == "" {
			return nil, fmt.Errorf("api_key is required")
		}
		return gw.ListWebhooks(ctx, apiKey)
	})
}

func registerCreateWebhook(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "create_webhook",
		Description: "Register a webhook to receive real-time event notifications. The webhook secret is returned only once — store it securely. Supported events: conversation.created, conversation.ended, message.created, lead.qualified, contact.created.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"url":    {Type: "string", Description: "Webhook URL to receive events"},
				"events": {Type: "array", Description: "List of event types to subscribe to"},
			},
			Required: []string{"url", "events"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		urlVal, _ := args["url"].(string)
		if apiKey == "" || urlVal == "" {
			return nil, fmt.Errorf("api_key and url are required")
		}
		events := parseStringSlice(args["events"])
		if len(events) == 0 {
			return nil, fmt.Errorf("events is required and must not be empty")
		}
		req := gateway.WebhookCreateRequest{
			URL:    urlVal,
			Events: events,
		}
		return gw.CreateWebhook(ctx, apiKey, req)
	})
}

func registerUpdateWebhook(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "update_webhook",
		Description: "Update a webhook's active status or subscribed events.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"webhook_id": {Type: "string", Description: "Webhook ID to update"},
				"is_active":  {Type: "boolean", Description: "Whether the webhook is active"},
				"events":     {Type: "array", Description: "List of event types to subscribe to"},
			},
			Required: []string{"webhook_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		webhookID, _ := args["webhook_id"].(string)
		if apiKey == "" || webhookID == "" {
			return nil, fmt.Errorf("api_key and webhook_id are required")
		}
		req := gateway.WebhookUpdateRequest{}
		if v, present := args["is_active"]; present {
			if b, ok := v.(bool); ok {
				req.IsActive = &b
			}
		}
		if events := parseStringSlice(args["events"]); len(events) > 0 {
			req.Events = events
		}
		return gw.UpdateWebhook(ctx, apiKey, webhookID, req)
	})
}

func registerDeleteWebhook(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "delete_webhook",
		Description: "Delete a webhook. This stops all event notifications to the registered URL.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"webhook_id": {Type: "string", Description: "Webhook ID to delete"},
			},
			Required: []string{"webhook_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		webhookID, _ := args["webhook_id"].(string)
		if apiKey == "" || webhookID == "" {
			return nil, fmt.Errorf("api_key and webhook_id are required")
		}
		if err := gw.DeleteWebhook(ctx, apiKey, webhookID); err != nil {
			return nil, err
		}
		return map[string]string{"status": "deleted"}, nil
	})
}
