import type { FastifyInstance } from 'fastify';
import { requireRole } from '../../lib/auth.js';
import { listTools, getTool } from './registry.js';
import type { McpCallRequest, McpCallResponse, McpToolRequest } from './types.js';

export async function toolRoutes(app: FastifyInstance) {
  /** List all registered tools */
  app.get('/tools', async req => {
    requireRole(req, 'viewer');
    return { tools: listTools() };
  });

  /** Execute a tool by name */
  app.post('/tools/call', async (req, reply): Promise<McpCallResponse> => {
    const body = req.body as McpCallRequest;

    if (!body?.name) {
      return reply.status(400).send({ error: 'Missing tool name' }) as never;
    }

    const tool = getTool(body.name);
    if (!tool) {
      return reply.status(404).send({ error: `Tool '${body.name}' not found` }) as never;
    }

    // Role check
    requireRole(req, tool.requiredRole);

    // Validate input
    const parsed = tool.inputSchema.safeParse(body.arguments ?? {});
    if (!parsed.success) {
      return reply.status(422).send({
        error: 'Invalid tool arguments',
        details: parsed.error.flatten(),
      }) as never;
    }

    // Audit log
    req.log.info(
      { tool: body.name, userId: req.jwtPayload?.sub, requestId: req.id },
      'mcp tool call'
    );

    try {
      const mcpReq: McpToolRequest = {
        id: req.id,
        headers: { authorization: req.headers.authorization },
        jwtPayload: req.jwtPayload,
        log: req.log,
      };
      const result = await tool.execute(parsed.data, mcpReq);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
      };
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      req.log.error({ tool: body.name, err }, 'mcp tool error');
      return {
        content: [{ type: 'text', text: `Error: ${message}` }],
        isError: true,
      };
    }
  });
}
