/**
 * Error Handling Utilities for Demo Bookings
 *
 * This module provides standardized error handling for the demo bookings feature.
 * Benefits:
 * - Consistent error responses
 * - Type-safe error handling
 * - Centralized logging
 * - Easy to modify error messages
 *
 * @module lib/staff-dashboard/demo-bookings/errors
 */

import { NextResponse } from 'next/server';
import { ERROR_MESSAGES, LOG_PREFIX } from './constants';

/**
 * Custom error class for demo booking operations
 *
 * Extends Error with additional context for better debugging.
 */
export class DemoBookingError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500,
    public details?: unknown
  ) {
    super(message);
    this.name = 'DemoBookingError';
  }
}

/**
 * Create standardized error response
 *
 * Returns a NextResponse with consistent error format.
 *
 * @param message - Error message to return
 * @param statusCode - HTTP status code (default: 500)
 * @param details - Additional error details for logging
 * @returns NextResponse with error
 *
 * @example
 * return createErrorResponse('Not found', 404);
 */
export function createErrorResponse(
  message: string,
  statusCode: number = 500,
  details?: unknown
): NextResponse {
  // Log error details (not sent to client)
  if (details) {
    console.error(`${LOG_PREFIX} ${message}`, details);
  } else {
    console.error(`${LOG_PREFIX} ${message}`);
  }

  // Return clean error to client (don't expose internal details)
  return NextResponse.json({ error: message }, { status: statusCode });
}

/**
 * Create unauthorized response (401)
 *
 * Standard response for authentication failures.
 *
 * @returns 401 Unauthorized response
 */
export function createUnauthorizedResponse(): NextResponse {
  return createErrorResponse(ERROR_MESSAGES.UNAUTHORIZED, 401);
}

/**
 * Create bad request response (400)
 *
 * Standard response for validation failures.
 *
 * @param errors - Array of validation errors
 * @returns 400 Bad Request response
 */
export function createBadRequestResponse(errors: string[]): NextResponse {
  console.error(`${LOG_PREFIX} Validation failed:`, errors);
  return NextResponse.json({ error: errors.join('; '), errors }, { status: 400 });
}

/**
 * Create database error response
 *
 * Standard response for database query failures.
 *
 * @param error - Error from database query
 * @param context - Context about what operation failed
 * @returns 500 Internal Server Error response
 */
export function createDatabaseErrorResponse(
  error: unknown,
  context: string
): NextResponse {
  const errorMessage = error instanceof Error ? error.message : 'Unknown database error';

  console.error(`${LOG_PREFIX} Database error during ${context}:`, {
    message: errorMessage,
    error,
  });

  // Don't expose database details to client
  return NextResponse.json(
    { error: ERROR_MESSAGES.FETCH_FAILED },
    { status: 500 }
  );
}

/**
 * Create success response with data
 *
 * Standard response format for successful operations.
 *
 * @param data - Data to return
 * @param statusCode - HTTP status code (default: 200)
 * @returns NextResponse with data
 *
 * @example
 * return createSuccessResponse({ bookings: [...] });
 */
export function createSuccessResponse<T>(
  data: T,
  statusCode: number = 200
): NextResponse {
  return NextResponse.json(data, { status: statusCode });
}

/**
 * Handle database query error
 *
 * Extracts useful information from database errors and logs appropriately.
 *
 * @param error - Error from database query
 * @param operation - Description of operation that failed
 * @returns Formatted error object
 */
export function handleDatabaseError(error: unknown, operation: string): {
  message: string;
  code: string;
  details: unknown;
} {
  if (error && typeof error === 'object' && 'message' in error) {
    const dbError = error as { message: string; code?: string; details?: unknown };

    console.error(`${LOG_PREFIX} Database error during ${operation}:`, {
      message: dbError.message,
      code: dbError.code,
      details: dbError.details,
    });

    return {
      message: dbError.message,
      code: dbError.code || 'UNKNOWN',
      details: dbError.details,
    };
  }

  console.error(`${LOG_PREFIX} Unknown error during ${operation}:`, error);

  return {
    message: 'Unknown error',
    code: 'UNKNOWN',
    details: error,
  };
}

/**
 * Wrap async handler with error catching
 *
 * Wraps an API route handler to catch and handle all errors automatically.
 *
 * @param handler - Async function to wrap
 * @returns Wrapped function with error handling
 *
 * @example
 * export const GET = withErrorHandler(async (request) => {
 *   // Your code here
 *   // Errors are automatically caught and formatted
 * });
 */
export function withErrorHandler<T extends unknown[], R>(
  handler: (...args: T) => Promise<R>
): (...args: T) => Promise<R | NextResponse> {
  return async (...args: T): Promise<R | NextResponse> => {
    try {
      return await handler(...args);
    } catch (error) {
      console.error(`${LOG_PREFIX} Unhandled error:`, error);

      return NextResponse.json(
        { error: 'Internal server error' },
        { status: 500 }
      ) as unknown as R | NextResponse;
    }
  };
}

/**
 * Log operation for debugging
 *
 * Structured logging for debugging and monitoring.
 *
 * @param operation - Operation being performed
 * @param details - Additional details
 *
 * @example
 * logOperation('fetch_bookings', { filters, count: result.length });
 */
export function logOperation(operation: string, details?: unknown): void {
  if (process.env.NODE_ENV === 'development') {
    console.log(`${LOG_PREFIX} ${operation}`, details || '');
  }
}

/**
 * Log warning
 *
 * @param message - Warning message
 * @param details - Additional details
 */
export function logWarning(message: string, details?: unknown): void {
  console.warn(`${LOG_PREFIX} ⚠️  ${message}`, details || '');
}

/**
 * Log success
 *
 * @param message - Success message
 * @param details - Additional details
 */
export function logSuccess(message: string, details?: unknown): void {
  if (process.env.NODE_ENV === 'development') {
    console.log(`${LOG_PREFIX} ✅ ${message}`, details || '');
  }
}
