/**
 * HTTP types for routing module.
 * These were previously in http-proxy and are now self-contained here.
 */
import * as plugins from '../../plugins.js';
import { HttpStatus as ProtocolHttpStatus, getStatusText as getProtocolStatusText } from '../../protocols/http/index.js';

/**
 * HTTP-specific event types
 */
export enum HttpEvents {
  REQUEST_RECEIVED = 'request-received',
  REQUEST_FORWARDED = 'request-forwarded',
  REQUEST_HANDLED = 'request-handled',
  REQUEST_ERROR = 'request-error',
}

// Re-export for backward compatibility with subset of commonly used codes
export const HttpStatus = {
  OK: ProtocolHttpStatus.OK,
  MOVED_PERMANENTLY: ProtocolHttpStatus.MOVED_PERMANENTLY,
  FOUND: ProtocolHttpStatus.FOUND,
  TEMPORARY_REDIRECT: ProtocolHttpStatus.TEMPORARY_REDIRECT,
  PERMANENT_REDIRECT: ProtocolHttpStatus.PERMANENT_REDIRECT,
  BAD_REQUEST: ProtocolHttpStatus.BAD_REQUEST,
  UNAUTHORIZED: ProtocolHttpStatus.UNAUTHORIZED,
  FORBIDDEN: ProtocolHttpStatus.FORBIDDEN,
  NOT_FOUND: ProtocolHttpStatus.NOT_FOUND,
  METHOD_NOT_ALLOWED: ProtocolHttpStatus.METHOD_NOT_ALLOWED,
  REQUEST_TIMEOUT: ProtocolHttpStatus.REQUEST_TIMEOUT,
  TOO_MANY_REQUESTS: ProtocolHttpStatus.TOO_MANY_REQUESTS,
  INTERNAL_SERVER_ERROR: ProtocolHttpStatus.INTERNAL_SERVER_ERROR,
  NOT_IMPLEMENTED: ProtocolHttpStatus.NOT_IMPLEMENTED,
  BAD_GATEWAY: ProtocolHttpStatus.BAD_GATEWAY,
  SERVICE_UNAVAILABLE: ProtocolHttpStatus.SERVICE_UNAVAILABLE,
  GATEWAY_TIMEOUT: ProtocolHttpStatus.GATEWAY_TIMEOUT,
} as const;

/**
 * Base error class for HTTP-related errors
 */
export class HttpError extends Error {
  constructor(message: string, public readonly statusCode: number = HttpStatus.INTERNAL_SERVER_ERROR) {
    super(message);
    this.name = 'HttpError';
  }
}

/**
 * Error related to certificate operations
 */
export class CertificateError extends HttpError {
  constructor(
    message: string,
    public readonly domain: string,
    public readonly isRenewal: boolean = false
  ) {
    super(`${message} for domain ${domain}${isRenewal ? ' (renewal)' : ''}`, HttpStatus.INTERNAL_SERVER_ERROR);
    this.name = 'CertificateError';
  }
}

/**
 * Error related to server operations
 */
export class ServerError extends HttpError {
  constructor(message: string, public readonly code?: string, statusCode: number = HttpStatus.INTERNAL_SERVER_ERROR) {
    super(message, statusCode);
    this.name = 'ServerError';
  }
}

/**
 * Error for bad requests
 */
export class BadRequestError extends HttpError {
  constructor(message: string) {
    super(message, HttpStatus.BAD_REQUEST);
    this.name = 'BadRequestError';
  }
}

/**
 * Error for not found resources
 */
export class NotFoundError extends HttpError {
  constructor(message: string = 'Resource not found') {
    super(message, HttpStatus.NOT_FOUND);
    this.name = 'NotFoundError';
  }
}

/**
 * Redirect configuration for HTTP requests
 */
export interface IRedirectConfig {
  source: string;
  destination: string;
  type: number;
  preserveQuery?: boolean;
}

/**
 * HTTP router configuration
 */
export interface IRouterConfig {
  routes: Array<{
    path: string;
    method?: string;
    handler: (req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse) => void | Promise<void>;
  }>;
  notFoundHandler?: (req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse) => void;
  errorHandler?: (error: Error, req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse) => void;
}

/**
 * HTTP request method types
 */
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';

/**
 * Helper function to get HTTP status text
 */
export function getStatusText(status: number): string {
  return getProtocolStatusText(status as ProtocolHttpStatus);
}

// Legacy interfaces for backward compatibility
export interface IDomainOptions {
  domainName: string;
  sslRedirect: boolean;
  acmeMaintenance: boolean;
  forward?: { ip: string; port: number };
  acmeForward?: { ip: string; port: number };
}

export interface IDomainCertificate {
  options: IDomainOptions;
  certObtained: boolean;
  obtainingInProgress: boolean;
  certificate?: string;
  privateKey?: string;
  expiryDate?: Date;
  lastRenewalAttempt?: Date;
}

// Backward compatibility exports
export { HttpError as Port80HandlerError };
export { CertificateError as CertError };
