/**
 * @fileoverview Formats errors into MCP-compliant API responses
 */

import { MCPError, MCPErrorInfo } from './mcp-errors.js';
import { toMCPError } from './mcp-error-converter.js';
import { createLogger } from '../logging/logger.js';
import type { ApiResponse } from '../../models/common.js';

const logger = createLogger('MCPErrorFormatter');

/**
 * Logs errors with appropriate log levels
 */
function logError(error: MCPError, context?: string): void {
  const logData = {
    code: error.code,
    category: error.category,
    message: error.message,
    context,
    retryable: error.retryable,
    userFriendly: error.userFriendly,
    details: error.details,
    stack: error.stack,
    cause: error.cause
      ? {
          name: error.cause.name,
          message: error.cause.message,
          stack: error.cause.stack,
        }
      : undefined,
  };

  // Choose log level based on error category
  switch (error.category) {
    case 'client_error':
    case 'validation_error':
    case 'authentication_error':
      logger.warn('Client error occurred', logData);
      break;

    case 'server_error':
    case 'internal_error':
      logger.error('Server error occurred', logData);
      break;

    case 'network_error':
    case 'transport_error':
      logger.warn('Network error occurred', logData);
      break;

    case 'resource_error':
      logger.info('Resource error occurred', logData);
      break;

    default:
      logger.error('Unknown error category', logData);
  }
}

/**
 * Creates an MCP-compliant error response
 */
export function createErrorResponse(error: unknown, context?: string): ApiResponse {
  const mcpError = toMCPError(error, context);

  // Log the error for debugging
  logError(mcpError, context);

  // Create user-friendly error message
  const errorData = {
    error: mcpError.userFriendly
      ? mcpError.message
      : 'An error occurred while processing your request',
    code: mcpError.code,
    category: mcpError.category,
    retryable: mcpError.retryable,
    ...(mcpError.details && { details: mcpError.details }),
    timestamp: mcpError.timestamp.toISOString(),
  };

  return {
    isError: true,
    content: [
      {
        type: 'text' as const,
        text: JSON.stringify(errorData, null, 2),
      },
    ],
  };
}

/**
 * Creates a validation error response
 */
export function createValidationErrorResponse(
  message: string,
  field?: string,
  value?: unknown
): ApiResponse {
  const details: Record<string, unknown> = {};
  if (field) details.field = field;
  if (value !== undefined) details.value = value;

  const errorInfo: MCPErrorInfo = {
    code: 'VALIDATION_ERROR',
    category: 'VALIDATION_ERROR',
    message: `Validation failed: ${message}`,
    retryable: false,
    userFriendly: true,
  };

  if (Object.keys(details).length > 0) {
    errorInfo.details = details;
  }

  const error = new MCPError(errorInfo);

  return createErrorResponse(error);
}

/**
 * Creates a resource not found error response
 */
export function createNotFoundResponse(resource: string, identifier?: string): ApiResponse {
  const details: Record<string, unknown> = { resource };
  if (identifier) details.identifier = identifier;

  const error = new MCPError({
    code: 'RESOURCE_NOT_FOUND',
    category: 'RESOURCE_ERROR',
    message: `Resource not found: ${resource}`,
    details,
    retryable: false,
    userFriendly: true,
  });

  return createErrorResponse(error);
}

// For backward compatibility, export a namespace-like object
export const MCPErrorFormatter = {
  createErrorResponse,
  createValidationErrorResponse,
  createNotFoundResponse,
};
