type LogLevel = 'log' | 'warn' | 'error';

interface LogOptions {
	context?: Record<string, any>;
	prefix?: string;
}

class Logger {
	private isDevelopment: boolean;

	constructor() {
		this.isDevelopment =
			typeof process === 'undefined' ||
			process?.env?.NODE_ENV === 'development' ||
			process?.env?.NODE_ENV === 'nitrogen';
	}

	private getCallerInfo(): string | null {
		try {
			const stack = new Error().stack;
			if (!stack) return null;

			// Parse stack trace to find the actual caller (skip logger internals)
			const lines = stack.split('\n');
			// Skip: Error, getCallerInfo, formatMessage, log/warn/error method, actual caller
			const callerLine = lines[5];

			if (!callerLine) return null;

			// Extract file:line:column from stack trace
			// Browser format: "    at functionName (file:line:column)"
			const match =
				callerLine.match(/\((.+):(\d+):(\d+)\)/) ||
				callerLine.match(/at (.+):(\d+):(\d+)/);
			if (!match) return null;

			const [, file, line, column] = match;
			// Get just the filename from the full path
			const filename = file.split('/').pop()?.split('?')[0] || file;

			return `${filename}:${line}:${column}`;
		} catch {
			return null;
		}
	}

	private formatMessage(
		level: LogLevel,
		message: string,
		options?: LogOptions
	): void {
		const prefix = options?.prefix || 'NitrogenClient';
		const caller = this.getCallerInfo();

		// Color schemes for different log levels
		const colors = {
			log: '#00bcd4', // Cyan
			warn: '#ff9800', // Orange
			error: '#f44336', // Red
		};

		const prefixStyle = `
			color: white;
			background-color: ${colors[level]};
			border-radius: 4px;
			padding: 2px 6px;
			font-weight: bold;
		`;

		const callerStyle = `
			color: #888;
			font-size: 0.9em;
		`;

		if (this.isDevelopment) {
			// Development: Show prefix, caller, and message inline
			const callerInfo = caller ? `%c ${caller}` : '';
			const styles = caller ? [prefixStyle, callerStyle] : [prefixStyle];

			console[level](
				`%c[${prefix}]${callerInfo} ${message}`,
				...styles,
				options?.context || ''
			);
		} else {
			// Production: Collapsed group with context
			console.groupCollapsed(`%c[${prefix}] ${message}`, prefixStyle);

			if (caller) {
				console.log(`Location: ${caller}`);
			}

			if (options?.context) {
				console[level]('Context:', options.context);
			} else {
				console[level](message);
			}

			console.groupEnd();
		}
	}

	log(message: string, options?: LogOptions): void {
		this.formatMessage('log', message, options);
	}

	warn(message: string, options?: LogOptions): void {
		this.formatMessage('warn', message, options);
	}

	error(message: string, options?: LogOptions): void {
		this.formatMessage('error', message, options);
	}
}

export const logger = new Logger();
