import type { Context, ErrorHandler } from 'hono';
import { z } from 'zod';

/**
 * Error response format
 */
export interface ErrorResponse {
  error: string;
  message: string;
  details?: unknown;
  stack?: string;
}

/**
 * Application error with status code
 */
export class AppError extends Error {
  constructor(
    public status: number,
    message: string,
    public details?: unknown
  ) {
    super(message);
    this.name = 'AppError';
  }
}

/**
 * Not found error
 */
export class NotFoundError extends AppError {
  constructor(message = 'Resource not found') {
    super(404, message);
    this.name = 'NotFoundError';
  }
}

/**
 * Validation error
 */
export class ValidationError extends AppError {
  constructor(message: string, details?: unknown) {
    super(400, message, details);
    this.name = 'ValidationError';
  }
}

/**
 * Global error handler middleware
 */
export const errorHandler: ErrorHandler = (err: Error, c: Context) => {
  const isDev = process.env.NODE_ENV !== 'production';

  // Handle Zod validation errors
  if (err instanceof z.ZodError) {
    return c.json<ErrorResponse>(
      {
        error: 'ValidationError',
        message: 'Request validation failed',
        details: err.errors,
      },
      400
    );
  }

  // Handle application errors
  if (err instanceof AppError) {
    return c.json<ErrorResponse>(
      {
        error: err.name,
        message: err.message,
        details: err.details,
        stack: isDev ? err.stack : undefined,
      },
      err.status
    );
  }

  // Handle unknown errors
  console.error('Unhandled error:', err);

  return c.json<ErrorResponse>(
    {
      error: 'InternalError',
      message: isDev ? err.message : 'An internal error occurred',
      stack: isDev ? err.stack : undefined,
    },
    500
  );
};
