import { Elysia } from "elysia";
import { Logger as PinoLogger, LoggerOptions as PinoLoggerOptions } from "pino";
type Pino = PinoLogger<never, boolean>;
type RequestInfo = Request;
type LogLevel = "DEBUG" | "INFO" | "WARNING" | "ERROR";
interface StoreData {
	beforeTime: bigint;
}
interface LogixlysiaStore {
	beforeTime?: bigint;
	logger: Logger;
	pino: Pino;
}
interface Transport {
	log: (level: LogLevel, message: string, meta?: Record<string, unknown>) => void | Promise<void>;
}
interface LogRotationConfig {
	compress?: boolean;
	compression?: "gzip";
	/**
	* Rotate at a fixed interval, e.g. '1d', '12h'.
	*/
	interval?: string;
	/**
	* Keep at most N files or keep files for a duration like '7d'.
	*/
	maxFiles?: number | string;
	/**
	* Max log file size before rotation, e.g. '10m', '5k', or a byte count.
	*/
	maxSize?: string | number;
}
interface LogFilter {
	/**
	* Array of log levels to allow. If specified, only logs with these levels will be processed.
	* If not specified, all log levels will be allowed.
	*/
	level?: LogLevel[];
}
/**
* Configuration for pino-pretty transport output.
*
* - `true`: Enable pretty printing with default options
* - `false` or `undefined`: Disable pretty printing
* - Object: Enable with custom pino-pretty options (colorize, translateTime, messageKey, errorKey, etc.)
*
* @see https://github.com/pinojs/pino-pretty#options
*/
type PrettyPrintConfig = boolean | Record<string, unknown>;
type LogPreset = "dev" | "prod" | "json";
interface Options {
	config?: {
		showStartupMessage?: boolean;
		startupMessageFormat?: "simple" | "banner";
		useColors?: boolean;
		ip?: boolean;
		timestamp?: {
			translateTime?: string;
		};
		customLogFormat?: string;
		/** Service name shown in `{service}` token (e.g. evlog-style `[my-app]`). */
		service?: string;
		/** Duration (ms) below this uses green; default 500. */
		slowThreshold?: number;
		/** Duration (ms) at or above this uses red + `{speed}` badge; default 1000. */
		verySlowThreshold?: number;
		/** Render `data.context` as tree lines under the main log line; default true. */
		showContextTree?: boolean;
		/** How many object nesting levels to expand in the context tree; default 1. */
		contextDepth?: number;
		/** Include query parameters in the logged URL path; default false. */
		logQueryParams?: boolean;
		/** Skip automatic WebSocket lifecycle logs from `wrapWs`; default false. */
		disableWebSocketLogging?: boolean;
		logFilter?: LogFilter;
		transports?: Transport[];
		useTransportsOnly?: boolean;
		disableInternalLogger?: boolean;
		disableFileLogging?: boolean;
		logFilePath?: string;
		logRotation?: LogRotationConfig;
		/**
		* Automatically redact sensitive information (PII) from logs.
		* Masks emails, IP addresses, Luhn-valid payment card numbers, and JWTs in strings and deeply nested objects.
		*/
		autoRedact?: boolean;
		pino?: (PinoLoggerOptions & {
			prettyPrint?: PrettyPrintConfig;
		}) | undefined;
	};
	/**
	* Opinionated defaults for common environments.
	* Explicit `config` fields override preset values.
	*/
	preset?: LogPreset;
}
interface Logger {
	debug: (request: RequestInfo, message: string, context?: Record<string, unknown>) => void;
	error: (request: RequestInfo, message: string, context?: Record<string, unknown>) => void;
	getContext: (key: RequestInfo | object) => Readonly<Record<string, unknown>>;
	handleHttpError: (request: RequestInfo, error: unknown, store: StoreData) => void;
	info: (request: RequestInfo, message: string, context?: Record<string, unknown>) => void;
	log: (level: LogLevel, request: RequestInfo, data: Record<string, unknown>, store: StoreData) => void;
	mergeContext: (key: RequestInfo | object, partial: Record<string, unknown>) => void;
	pino: Pino;
	warn: (request: RequestInfo, message: string, context?: Record<string, unknown>) => void;
}
interface LogixlysiaContext {
	request: Request;
	store: LogixlysiaStore;
}
/** HTTP `Request` or WebSocket instance for accumulated context. */
type ContextKey = Request | object;
interface RequestContextStore {
	clearContext: (key: ContextKey) => void;
	getContext: (key: ContextKey) => Readonly<Record<string, unknown>>;
	mergeContext: (key: ContextKey, partial: Record<string, unknown>) => void;
}
interface WebSocketLike {
	readonly data?: {
		store?: {
			logger?: Logger;
		};
	};
	readonly id?: string;
}
interface WsHandlerHooks<
	TMessage = unknown,
	TWs extends WebSocketLike = WebSocketLike
> {
	close?: (ws: TWs) => void;
	message?: (ws: TWs, message: TMessage) => void;
	open?: (ws: TWs) => void;
}
declare const createWsHandlerWrapper: (options: Options, logger: Logger, contextStore: RequestContextStore) => <
	TMessage,
	TWs extends WebSocketLike,
	const THooks extends WsHandlerHooks<TMessage, TWs>
>(path: string, hooks: THooks) => THooks;
/** Applies preset defaults; explicit `config` keys override preset values. */
declare const resolveOptions: (options?: Options) => Options;
import pino from "pino";
declare const createLogger: (options?: Options, pinoFactory?: typeof pino, externalContextStore?: RequestContextStore) => Logger;
/** Plugin entry: shares one request-context store across the Elysia lifecycle. */
declare const createPluginLogger: (options: Options, contextStore: RequestContextStore) => Logger;
/**
* Empty singleton slots must not use `Record<string, never>`: intersecting that with Elysia's `Context`
* makes every key (including `store`) become `never` because each key is merged with `never`.
*/
interface EmptyElysiaSlot {
	readonly __logixlysiaEmpty?: never;
}
/**
* Explicit singleton without Elysia's `SingletonBase` `Record<string, unknown>` on decorator/derive/resolve so
* merged `Context` and WebSocket `ws.data` keep precise keys after `.use(logixlysia())`.
*/
interface LogixlysiaSingleton {
	decorator: EmptyElysiaSlot;
	derive: EmptyElysiaSlot;
	resolve: EmptyElysiaSlot;
	store: LogixlysiaStore;
}
type Logixlysia = Elysia<"", LogixlysiaSingleton>;
type LogixlysiaPlugin = Logixlysia & {
	wrapWs: ReturnType<typeof createWsHandlerWrapper>;
};
declare const logixlysia: (rawOptions?: Options) => LogixlysiaPlugin;
export { resolveOptions, logixlysia, logixlysia as default, createWsHandlerWrapper, createPluginLogger, createLogger, WsHandlerHooks, Transport, StoreData, Pino, Options, LogixlysiaStore, LogixlysiaSingleton, LogixlysiaPlugin, LogixlysiaContext, Logixlysia, Logger, LogPreset, LogLevel, EmptyElysiaSlot };
