import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { captureSentryError, setSentryContext, setSentryUser } from '@shieldai/monitoring';

export interface ErrorResponse {
  error: string;
  message: string;
  statusCode: number;
  code?: string;
  details?: Record<string, unknown>;
  timestamp: string;
  path: string;
}

export async function errorHandlingMiddleware(fastify: FastifyInstance) {
  // Custom error handler
  fastify.setErrorHandler((error, request: FastifyRequest, reply: FastifyReply) => {
    const err = error as Error & { statusCode?: number; code?: string };
    const response: ErrorResponse = {
      error: err.name || 'Internal Server Error',
      message: err.message || 'An unexpected error occurred',
      statusCode: err.statusCode || 500,
      code: err.code,
      timestamp: new Date().toISOString(),
      path: request.url,
    };

    // Send to Sentry (5xx errors only)
    if (response.statusCode >= 500) {
      const userId = (request as FastifyRequest & { user?: { id?: string } }).user?.id;
      if (userId) setSentryUser(userId);
      setSentryContext('request', {
        method: request.method,
        url: request.url,
        userAgent: request.headers['user-agent'],
        requestId: request.id,
      });
      captureSentryError(err, {
        statusCode: String(response.statusCode),
        path: request.url,
        method: request.method,
      });
    }

    // Log error
    fastify.log.error({
      error: response,
      stack: err.stack,
      method: request.method,
      userAgent: request.headers['user-agent'],
    });

    // Send standardized error response
    reply.status(response.statusCode).send(response);
  });

  // 404 handler
  fastify.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {
    reply.status(404).send({
      error: 'Not Found',
      message: `Route ${request.method} ${request.url} not found`,
      statusCode: 404,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  });

  // Validation error handler
  fastify.addHook('onError', async (request: FastifyRequest, reply: FastifyReply, error) => {
    if (error.validation) {
      reply.status(400).send({
        error: 'Validation Error',
        message: 'Request validation failed',
        statusCode: 400,
        code: 'VALIDATION_ERROR',
        details: error.validation,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
    }
  });
}
