import { Container } from 'inversify';
import { Application } from 'express';
import { ServerOptions } from 'ws';
import { IncomingMessage } from 'http';
import { Socket } from 'net';

/**
 * IMessage: Interface for WebSocket messages.
 *
 * This interface defines the structure of messages exchanged between WebSocket clients and the server.
 * It is generic, allowing the content of the message to be of any type.
 *
 * ## Properties:
 * - **sender** (string): The identifier of the sender of the message.
 * - **content** (T): The content of the message. The type `T` is generic and defaults to `any`.
 */
interface IMessage<T = any> {
    /**
     * The identifier of the sender of the message.
     */
    sender: string;
    /**
     * The content of the message. The type is generic and can represent any structure or data.
     */
    content: T;
}

/**
 * IConfig: Interface for application configuration settings.
 *
 * This interface defines the structure of the configuration object required by the application,
 * including server options, lifecycle hooks, and additional customizations.
 *
 * ## Properties:
 * - **port** (number): The port number on which the server will run.
 * - **secretKey** (string): A secret key used for token generation and authentication.
 * - **tokenExpiry** (string): The duration for which generated tokens remain valid.
 * - **wsOptions** (ServerOptions | undefined): Optional WebSocket server options.
 * - **hooks** (object | undefined): Optional lifecycle hooks for WebSocket message processing.
 *   - **beforeSend** (Function | undefined): Hook executed before a message is broadcasted.
 *   - **afterSend** (Function | undefined): Hook executed after a message is broadcasted.
 * - **enableLogging** (boolean | undefined): Flag to enable or disable logging across the application.
 * - **setupRoutes** (Function | undefined): Callback for setting up application routes.
 * - **onMessage** (Function | undefined): Custom handler for processing incoming WebSocket messages.
 */
interface IConfig {
    /**
     * The port number on which the server will run.
     */
    port: number;
    /**
     * A secret key used for token generation and authentication.
     */
    secretKey: string;
    /**
     * The duration for which generated tokens remain valid (e.g., '1h', '2d').
     */
    tokenExpiry: string;
    /**
     * Optional WebSocket server options.
     */
    wsOptions?: ServerOptions;
    /**
     * Optional lifecycle hooks for WebSocket message processing.
     */
    hooks?: {
        /**
         * Hook executed before a message is broadcasted.
         *
         * @param {IMessage<any>} message - The message being processed.
         */
        beforeSend?: (message: IMessage<any>) => void;
        /**
         * Hook executed after a message is broadcasted.
         *
         * @param {IMessage<any>} message - The message that was processed.
         */
        afterSend?: (message: IMessage<any>) => void;
    };
    /**
     * Flag to enable or disable logging across the application.
     */
    enableLogging?: boolean;
    /**
     * Callback for setting up application routes.
     *
     * @param {Application} app - The Express application instance.
     */
    setupRoutes?: (app: Application) => void;
    /**
     * Custom handler for processing incoming WebSocket messages.
     *
     * @param {IMessage<any>} message - The incoming WebSocket message.
     */
    onMessage?: (message: IMessage<any>) => void;
}

/**
 * Creates and configures a Dependency Injection (DI) container.
 * This container is responsible for managing and injecting dependencies
 * across the application using the InversifyJS library.
 *
 * @param {Partial<IConfig>} configOptions - Configuration options for initializing the application.
 * @returns {Container} - A configured DI container instance.
 *
 * The function performs the following bindings:
 * - Binds `IConfig` to a dynamic instance of `Config` with the provided configuration options.
 * - Binds `ILogger` to a singleton instance of `LoggerService` for logging functionalities.
 * - Binds `IAuthService` to a singleton instance of `AuthService` for authentication-related operations.
 * - Binds `IWebSocketService` to a singleton instance of `WebSocketService` for WebSocket handling.
 * - Binds `WebSocketController` to a singleton instance for managing WebSocket events and connections.
 *
 * Each dependency is registered with a singleton scope to ensure one shared instance across the application.
 */
declare function createContainer(configOptions: Partial<IConfig>): Container;

declare const TYPES: {
    ILogger: string;
    IAuthService: string;
    IWebSocketService: string;
    WebSocketController: string;
    IConfig: string;
};

/**
 * ILogger: Interface for logging functionality.
 *
 * This interface defines the methods required for logging messages, warnings, and errors
 * throughout the application. It allows consistent logging behavior across different modules.
 *
 * ## Methods:
 * - **error**: Logs an error message.
 * - **warn**: Logs a warning message.
 * - **log**: Logs a general informational message.
 */
interface ILogger {
    /**
     * Logs an error message.
     *
     * @param {string} message - The error message to be logged.
     */
    error(message: string): void;
    /**
     * Logs a warning message.
     *
     * @param {string} message - The warning message to be logged.
     */
    warn(message: string): void;
    /**
     * Logs a general informational message.
     *
     * @param {string} message - The message to be logged.
     */
    log(message: string): void;
}

/**
 * IAuthService: Interface for authentication services.
 *
 * This interface defines the contract for an authentication service, which is responsible
 * for generating and verifying authentication tokens to ensure secure user access and
 * identification within the application.
 */
interface IAuthService {
    /**
     * Generates a secure token for a given username.
     *
     * @param {string} username - The username for which the token will be generated.
     * @returns {string} - A string representing the generated authentication token.
     */
    generateToken(username: string): string;
    /**
     * Verifies the provided token and retrieves the associated username if the token is valid.
     *
     * @param {string} token - The authentication token to be verified.
     * @returns {string | null} - The username associated with the token if valid, or null if invalid.
     */
    verifyToken(token: string): string | null;
}

/**
 * IWebSocketService: Interface for WebSocket service operations.
 *
 * This interface defines the methods required for managing WebSocket communication,
 * specifically for broadcasting messages to connected clients.
 *
 * ## Methods:
 * - **broadcastMessage**: Sends a message to all connected WebSocket clients.
 */
interface IWebSocketService {
    /**
     * Broadcasts a message to all connected WebSocket clients.
     *
     * @param {IMessage<any>} message - The message to be broadcasted.
     */
    broadcastMessage(message: IMessage<any>): void;
}

/**
 * WebSocketController: A class for managing WebSocket server and client interactions.
 *
 * This controller initializes a WebSocket server, handles client authentication and messaging,
 * and supports custom lifecycle hooks for message processing. It is designed to integrate
 * with dependency-injected services for logging, authentication, and configuration.
 *
 * ## Responsibilities:
 * - Initializes a WebSocket server (`wss`) using provided configuration options.
 * - Manages WebSocket client connections and tracks them in a `Map`.
 * - Authenticates clients using token-based authentication.
 * - Processes and broadcasts messages between connected clients.
 * - Provides hooks for pre-processing and post-processing messages.
 * - Logs key events such as connections, disconnections, and errors.
 *
 * ## Dependencies:
 * - `IWebSocketService`: Provides utility functions for WebSocket operations.
 * - `ILogger`: Handles logging of events and errors.
 * - `IAuthService`: Manages token-based client authentication.
 * - `IConfig`: Supplies configuration for the WebSocket server and hooks.
 */
declare class WebSocketController {
    private webSocketService;
    private logger;
    private authService;
    private config;
    /**
     *
     * @private
     * @type {WebSocketServer}
     * @memberof WebSocketController
     */
    private wss;
    /**
     *
     * @private
     * @type {Map<WebSocket, string>}
     * @memberof WebSocketController
     */
    private clients;
    /**
     *
     * @private
     * @memberof WebSocketController
     */
    private beforeSend?;
    /**
     *
     * @private
     * @memberof WebSocketController
     */
    private afterSend?;
    /**
     *
     * @private
     * @memberof WebSocketController
     */
    private onMessage?;
    /**
     * Constructor: Initializes the WebSocketController and sets up the WebSocket server.
     *
     * @param {IWebSocketService} webSocketService - Utility service for WebSocket operations.
     * @param {ILogger} logger - Logger service for monitoring and debugging.
     * @param {IAuthService} authService - Authentication service for verifying tokens.
     * @param {IConfig} config - Configuration object for WebSocket server and hooks.
     */
    constructor(webSocketService: IWebSocketService, logger: ILogger, authService: IAuthService, config: IConfig);
    /**
     * Dynamically sets lifecycle hooks for message processing.
     *
     * @param {Function} [beforeSend] - Hook executed before a message is broadcasted.
     * @param {Function} [afterSend] - Hook executed after a message is broadcasted.
     */
    setLifecycleHooks(beforeSend?: (message: IMessage<any>) => void, afterSend?: (message: IMessage<any>) => void): void;
    /**
     * Handles HTTP-to-WebSocket upgrade requests.
     *
     * @param {IncomingMessage} request - The incoming HTTP upgrade request.
     * @param {Socket} socket - The network socket for the connection.
     * @param {Buffer} head - The first packet of the upgraded stream.
     */
    handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer): void;
    /**
     * Handles a new WebSocket connection, authenticates the client, and sets up event listeners.
     *
     * @private
     * @param {WebSocket} ws - The WebSocket instance for the connected client.
     * @param {IncomingMessage} request - The incoming HTTP request for the connection.
     */
    private onConnection;
    /**
     * Broadcasts a message to all connected WebSocket clients.
     *
     * @private
     * @param {IMessage<any>} message - The message to be broadcasted.
     */
    private broadcastMessage;
    /**
     * Extracts the token from a WebSocket request URL for authentication.
     *
     * @private
     * @param {string | undefined} url - The URL from which to extract the token.
     * @returns {string | null} - The extracted token or null if not found.
     */
    private extractToken;
    /**
     * Gracefully shuts down the WebSocket server and logs the closure.
     */
    close(): void;
}

/**
 * IWebSocketManagerOptions: Interface for configuring the WebSocket manager.
 *
 * This interface defines the optional configuration properties for setting up the WebSocket manager,
 * including server options, lifecycle hooks, and logging settings.
 *
 * ## Properties:
 * - **port** (number | undefined): The port number for the WebSocket server.
 * - **secretKey** (string | undefined): The secret key used for token generation and authentication.
 * - **tokenExpiry** (string | undefined): The expiration duration for generated tokens.
 * - **enableLogging** (boolean | undefined): Flag to enable or disable logging.
 * - **wsOptions** (ServerOptions | undefined): Additional options for the WebSocket server.
 * - **setupRoutes** (Function | undefined): Callback for setting up application routes.
 * - **beforeSend** (Function | undefined): Hook executed before a message is broadcasted.
 * - **afterSend** (Function | undefined): Hook executed after a message is broadcasted.
 * - **onMessage** (Function | undefined): Custom handler for processing incoming WebSocket messages.
 */
interface IWebSocketManagerOptions {
    /**
     * The port number for the WebSocket server.
     */
    port?: number;
    /**
     * The secret key used for token generation and authentication.
     */
    secretKey?: string;
    /**
     * The expiration duration for generated tokens (e.g., '1h', '2d').
     */
    tokenExpiry?: string;
    /**
     * Flag to enable or disable logging.
     */
    enableLogging?: boolean;
    /**
     * Additional options for the WebSocket server.
     */
    wsOptions?: ServerOptions;
    /**
     * Callback for setting up application routes.
     *
     * @param {Application} app - The Express application instance.
     */
    setupRoutes?: (app: Application) => void;
    /**
     * Hook executed before a message is broadcasted.
     *
     * @param {IMessage<any>} message - The message being processed.
     */
    beforeSend?: (message: IMessage<any>) => void;
    /**
     * Hook executed after a message is broadcasted.
     *
     * @param {IMessage<any>} message - The message that was processed.
     */
    afterSend?: (message: IMessage<any>) => void;
    /**
     * Custom handler for processing incoming WebSocket messages.
     *
     * @param {IMessage<any>} message - The incoming WebSocket message.
     */
    onMessage?: (message: IMessage<any>) => void;
}
/**
 * IWebSocketManager: Interface for managing the WebSocket server.
 *
 * This interface defines the core functionalities of the WebSocket manager, including
 * starting and stopping the server, and generating authentication tokens.
 *
 * ## Methods:
 * - **start**: Starts the WebSocket server.
 * - **stop**: Stops the WebSocket server.
 * - **generateToken**: Generates a token for a given username.
 */
interface IWebSocketManager {
    /**
     * Starts the WebSocket server.
     */
    start(): void;
    /**
     * Stops the WebSocket server.
     */
    stop(): void;
    /**
     * Generates a token for a given username.
     *
     * @param {string} username - The username for which the token is generated.
     * @returns {string} - A string representing the generated token.
     */
    generateToken(username: string): string;
}

/**
 * User: A class representing a user in the system.
 *
 * This class encapsulates the basic properties of a user, such as the username,
 * and provides a simple structure for managing user-related information.
 *
 * ## Properties:
 * - **username** (string): The unique identifier or name of the user.
 */
declare class User {
    username: string;
    /**
     * Creates a new instance of the User class.
     *
     * @param {string} username - The unique identifier or name of the user.
     */
    constructor(username: string);
}

/**
 * AuthService: A service class for managing authentication.
 *
 * This service implements the `IAuthService` interface and provides functionality
 * for generating and verifying authentication tokens using JSON Web Tokens (JWT).
 *
 * ## Dependencies:
 * - **IConfig**: Provides the secret key and token expiry settings for token management.
 *
 * ## Responsibilities:
 * - Generate JWT tokens for user authentication.
 * - Verify the validity of JWT tokens and extract the associated username.
 */
declare class AuthService implements IAuthService {
    private config;
    private secretKey;
    private tokenExpiry;
    /**
     * Constructor: Initializes the AuthService with configuration settings.
     *
     * @param {IConfig} config - The configuration object providing the secret key and token expiry.
     */
    constructor(config: IConfig);
    /**
     * Generates a JWT token for the given username.
     *
     * @param {string} username - The username for which the token is generated.
     * @returns {string} - A JWT token representing the authenticated user.
     */
    generateToken(username: string): string;
    /**
     * Verifies the provided JWT token and retrieves the associated username.
     *
     * @param {string} token - The JWT token to verify.
     * @returns {string | null} - The username if the token is valid, or null if invalid.
     */
    verifyToken(token: string): string | null;
}

/**
 * LoggerService: A service class for managing application logging.
 *
 * This service implements the `ILogger` interface and provides methods for logging errors,
 * warnings, and general informational messages. The logging functionality can be controlled
 * through the configuration to enable or disable logging.
 *
 * ## Dependencies:
 * - **IConfig**: Supplies configuration settings, including the `enableLogging` flag.
 *
 * ## Responsibilities:
 * - Logs error messages unconditionally.
 * - Logs warnings and informational messages conditionally, based on the `enableLogging` flag.
 */
declare class LoggerService implements ILogger {
    private config;
    private enableLogging;
    /**
     * Constructor: Initializes the LoggerService with configuration settings.
     *
     * @param {IConfig} config - The configuration object providing logging settings.
     */
    constructor(config: IConfig);
    /**
     * Logs an error message.
     *
     * @param {string} message - The error message to log.
     */
    error(message: string): void;
    /**
     * Logs a warning message if logging is enabled.
     *
     * @param {string} message - The warning message to log.
     */
    warn(message: string): void;
    /**
     * Logs an informational message if logging is enabled.
     *
     * @param {string} message - The message to log.
     */
    log(message: string): void;
}

/**
 * WebSocketService: A service class for managing WebSocket operations.
 *
 * This service implements the `IWebSocketService` interface and provides functionality
 * for broadcasting messages to connected WebSocket clients.
 *
 * ## Dependencies:
 * - **ILogger**: Used for logging message broadcasting activities.
 *
 * ## Responsibilities:
 * - Logs the broadcasting of messages using the injected logger service.
 */
declare class WebSocketService implements IWebSocketService {
    private logger;
    /**
     * Constructor: Initializes the WebSocketService with a logger dependency.
     *
     * @param {ILogger} logger - The logger service for logging operations.
     */
    constructor(logger: ILogger);
    /**
     * Logs a message broadcasting activity.
     *
     * @param {IMessage<any>} message - The message to be broadcasted.
     */
    broadcastMessage(message: IMessage<any>): void;
}

/**
 * Config: A class implementing the `IConfig` interface to provide configuration settings for the application.
 *
 * This class encapsulates various configuration options, including server settings, lifecycle hooks,
 * and logging preferences. It allows default values to be overridden using a partial configuration object.
 *
 * ## Properties:
 * - **port**: The port number on which the server will run (default: 8080).
 * - **secretKey**: The secret key used for token generation and authentication (default: 'default_secret_key').
 * - **tokenExpiry**: The duration for which generated tokens remain valid (default: '1h').
 * - **wsOptions**: Optional WebSocket server options.
 * - **hooks**: Optional lifecycle hooks for WebSocket message processing.
 * - **enableLogging**: Whether to enable logging (default: `true`).
 * - **setupRoutes**: Optional callback for setting up application routes.
 * - **onMessage**: Optional custom handler for processing incoming WebSocket messages.
 */
declare class Config implements IConfig {
    /**
     * The port number on which the server will run.
     *
     * @type {number}
     * @memberof Config
     */
    port: number;
    /**
     * The secret key used for token generation and authentication.
     *
     * @type {string}
     * @memberof Config
     */
    secretKey: string;
    /**
     * The duration for which generated tokens remain valid (e.g., '1h', '2d').
     *
     * @type {string}
     * @memberof Config
     */
    tokenExpiry: string;
    /**
     * Optional WebSocket server options for customizing behavior.
     *
     * @type {ServerOptions}
     * @memberof Config
     */
    wsOptions?: ServerOptions;
    /**
     * Optional lifecycle hooks for processing WebSocket messages.
     *
     * @memberof Config
     */
    hooks?: {
        /**
         * Hook executed before a message is broadcasted.
         *
         * @param {IMessage<any>} message - The message being processed.
         */
        beforeSend?: (message: IMessage<any>) => void;
        /**
         * Hook executed after a message is broadcasted.
         *
         * @param {IMessage<any>} message - The message that was processed.
         */
        afterSend?: (message: IMessage<any>) => void;
    };
    /**
     * Indicates whether logging is enabled. Defaults to `true`.
     *
     * @type {boolean}
     * @memberof Config
     */
    enableLogging?: boolean;
    /**
     * Optional callback for setting up application routes.
     *
     * @param {Application} app - The Express application instance.
     * @memberof Config
     */
    setupRoutes?: (app: Application) => void;
    /**
     * Optional custom handler for processing incoming WebSocket messages.
     *
     * @param {IMessage<any>} message - The incoming WebSocket message.
     * @memberof Config
     */
    onMessage?: (message: IMessage<any>) => void;
    /**
     * Constructor: Initializes the Config class with provided options or defaults.
     *
     * @param {Partial<IConfig>} options - A partial configuration object to override defaults.
     */
    constructor(options?: Partial<IConfig>);
}

/**
 * WebSocketManager: A class for managing WebSocket server and HTTP server interactions.
 *
 * This class is responsible for initializing the HTTP and WebSocket servers, configuring middleware,
 * managing lifecycle hooks, and delegating WebSocket operations to the WebSocketController.
 *
 * ## Responsibilities:
 * - Initializes the HTTP server and Express application.
 * - Configures WebSocket functionality and integrates WebSocketController for handling WebSocket events.
 * - Manages lifecycle hooks for WebSocket message processing.
 * - Provides methods to start, stop the server, and generate authentication tokens.
 *
 * ## Dependencies:
 * - Uses `createContainer` to resolve and inject dependencies including:
 *   - `ILogger`: For logging server and WebSocket events.
 *   - `IAuthService`: For token generation and authentication.
 *   - `IWebSocketService`: For WebSocket operations.
 *   - `WebSocketController`: To handle WebSocket connections and messaging.
 * - Accepts `IWebSocketManagerOptions` to customize behavior and configuration.
 */
declare class WebSocketManager implements IWebSocketManager {
    private options;
    /**
     *
     * @private
     * @type {Application}
     * @memberof WebSocketManager
     */
    private app;
    /**
     *
     * @private
     * @type {http.Server}
     * @memberof WebSocketManager
     */
    private server;
    /**
     *
     * @private
     * @type {ILogger}
     * @memberof WebSocketManager
     */
    private logger;
    /**
     *
     * @private
     * @type {IAuthService}
     * @memberof WebSocketManager
     */
    private authService;
    /**
     *
     * @private
     * @type {IWebSocketService}
     * @memberof WebSocketManager
     */
    private webSocketService;
    /**
     *
     * @private
     * @type {WebSocketController}
     * @memberof WebSocketManager
     */
    private webSocketController;
    /**
     *
     * @private
     * @type {number}
     * @memberof WebSocketManager
     */
    private port;
    /**
     * Constructor: Initializes the WebSocketManager with provided options.
     *
     * @param {IWebSocketManagerOptions} [options={}] - Optional configuration for the WebSocket manager.
     */
    constructor(options?: IWebSocketManagerOptions);
    /**
     *Configures middleware for the Express application.
     *
     * @private
     * @memberof WebSocketManager
     */
    private setupMiddleware;
    /**
     * Configures WebSocket upgrade handling and delegates it to WebSocketController.
     *
     * @private
     * @memberof WebSocketManager
     */
    private setupWebSocket;
    /**
     * Starts the HTTP server and WebSocket server.
     *
     * @memberof WebSocketManager
     */
    start(): void;
    /**
     * Stops the HTTP server and closes the WebSocket server.
     *
     * @memberof WebSocketManager
     */
    stop(): void;
    /**
     * Generates an authentication token for the given username.
     *
     * @param {string} username - The username for which the token is generated.
     * @returns {string} - A JWT token representing the authenticated user.
     */
    generateToken(username: string): string;
}

export { AuthService, Config, type IAuthService, type IConfig, type ILogger, type IMessage, type IWebSocketManager, type IWebSocketManagerOptions, type IWebSocketService, LoggerService, TYPES, User, WebSocketController, WebSocketManager, WebSocketService, createContainer };
