/**
 * Error Handler Middleware
 */

import type { Context } from 'hono';
import { HTTP_STATUS, ERROR_MESSAGES } from '../config/constants';
import { env } from '../config/env';

/** Custom application error */
export class AppError extends Error {
  constructor(
    public statusCode: number,
    message: string,
    public code?: string
  ) {
    super(message);
    this.name = 'AppError';
  }
}

/** Not found error */
export class NotFoundError extends AppError {
  constructor(resource: string = 'Resource') {
    super(HTTP_STATUS.NOT_FOUND, `${resource} not found`, 'NOT_FOUND');
  }
}

/** Unauthorized error */
export class UnauthorizedError extends AppError {
  constructor(message: string = ERROR_MESSAGES.UNAUTHORIZED) {
    super(HTTP_STATUS.UNAUTHORIZED, message, 'UNAUTHORIZED');
  }
}

/** Bad request error */
export class BadRequestError extends AppError {
  constructor(message: string) {
    super(HTTP_STATUS.BAD_REQUEST, message, 'BAD_REQUEST');
  }
}

/**
 * Global error handler for Hono onError
 */
export function errorHandler(err: Error, c: Context): Response {
  console.error('[ErrorHandler]', err);

  // Handle known app errors
  if (err instanceof AppError) {
    return c.json(
      {
        error: err.message,
        code: err.code,
      },
      err.statusCode as 400 | 401 | 403 | 404 | 500
    );
  }

  // Handle unknown errors
  const message = env.NODE_ENV === 'production'
    ? ERROR_MESSAGES.INTERNAL_ERROR
    : err.message;

  return c.json(
    {
      error: message,
      code: 'INTERNAL_ERROR',
    },
    HTTP_STATUS.INTERNAL_SERVER_ERROR
  );
}

/**
 * Not found handler (for unmatched routes)
 */
export function notFoundHandler(c: Context): Response {
  return c.json(
    {
      error: 'Endpoint not found',
      code: 'NOT_FOUND',
    },
    HTTP_STATUS.NOT_FOUND
  );
}
