/**
 * Webhooks MCP tools — webhooks.*
 *
 * Backed by: platform-service (port 4003) — webhooks module.
 * All tools require admin role.
 */

import { z } from 'zod';
import { registerTool } from '../tools/registry.js';
import { config } from '../../lib/config.js';
import {
  webhooksListSubscriptions,
  webhooksCreate,
  webhooksGet,
  webhooksUpdate,
  webhooksDelete,
  webhooksListDeliveries,
  webhooksTest,
  webhooksRotateSecret,
} from '../../lib/platform-client.js';
import type { McpToolRequest } from '../tools/types.js';

const tokenOf = (req: McpToolRequest) => req.headers.authorization?.slice(7);

// ── webhooks.listSubscriptions ────────────────────────────────────────────────

registerTool({
  name: 'webhooks.listSubscriptions',
  description:
    'List all webhook subscriptions for a product (url, events, enabled, createdAt). Secrets are redacted. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return webhooksListSubscriptions(args.productId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── webhooks.create ───────────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.create',
  description:
    'Create a new webhook subscription. The signing secret is returned ONCE at creation — store it securely. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
    url: z.string().url().describe('HTTPS endpoint URL that will receive events'),
    events: z
      .array(z.string())
      .min(1)
      .describe('Event types to subscribe to (e.g. ["user.created", "session.completed"])'),
    description: z.string().optional().describe('Human-readable description of this subscription'),
    enabled: z.boolean().optional().default(true),
  }),
  async execute(args, req) {
    return webhooksCreate(args, { token: tokenOf(req), requestId: req.id });
  },
});

// ── webhooks.get ──────────────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.get',
  description:
    'Get a single webhook subscription by ID. Secret is partially redacted (first 8 chars shown). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID'),
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return webhooksGet(args.subscriptionId, args.productId, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── webhooks.update ───────────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.update',
  description:
    'Update a webhook subscription (url, events list, enabled state, or description). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID'),
    productId: z.string().min(1).describe('Product ID'),
    url: z.string().url().optional().describe('New endpoint URL'),
    events: z.array(z.string()).optional().describe('Replacement event types list'),
    enabled: z.boolean().optional().describe('Enable or disable this subscription'),
    description: z.string().optional().describe('Updated description'),
  }),
  async execute(args, req) {
    const { subscriptionId, productId, ...updates } = args;
    return webhooksUpdate(subscriptionId, productId, updates, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── webhooks.delete ───────────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.delete',
  description: 'Permanently delete a webhook subscription. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID to delete'),
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return webhooksDelete(args.subscriptionId, args.productId, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── webhooks.listDeliveries ───────────────────────────────────────────────────

registerTool({
  name: 'webhooks.listDeliveries',
  description:
    'List recent delivery attempts for a webhook subscription (status, event, attempts, responseCode). Useful for debugging failed deliveries. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID'),
    limit: z.coerce.number().min(1).max(config.QUERY_MAX_LIMIT).default(config.QUERY_DEFAULT_LIMIT),
  }),
  async execute(args, req) {
    return webhooksListDeliveries(args.subscriptionId, args.limit, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── webhooks.test ─────────────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.test',
  description:
    'Send a test event payload to a webhook subscription to verify the endpoint is reachable and responding. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID to test'),
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return webhooksTest(args.subscriptionId, args.productId, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── webhooks.rotateSecret ─────────────────────────────────────────────────────

registerTool({
  name: 'webhooks.rotateSecret',
  description:
    'Rotate the HMAC signing secret for a webhook subscription. The new secret is returned ONCE — update your consumer immediately. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    subscriptionId: z.string().min(1).describe('Webhook subscription ID'),
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return webhooksRotateSecret(args.subscriptionId, args.productId, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});
