/**
 * Event Bus
 * イベントバスシステム
 */

/**
 * シンプルなイベントバスクラス
 */
class EventBus {
	constructor() {
		this.events = {};
	}

	/**
	 * イベントリスナーを登録
	 * @param {string}   event    イベント名
	 * @param {Function} callback コールバック関数
	 */
	on( event, callback ) {
		if ( ! this.events[ event ] ) {
			this.events[ event ] = [];
		}
		this.events[ event ].push( callback );
	}

	/**
	 * イベントリスナーを削除
	 * @param {string}   event    イベント名
	 * @param {Function} callback コールバック関数
	 */
	off( event, callback ) {
		if ( ! this.events[ event ] ) {
			return;
		}

		this.events[ event ] = this.events[ event ].filter(
			( cb ) => cb !== callback
		);
	}

	/**
	 * イベントを発火
	 * @param {string} event イベント名
	 * @param {*}      data  イベントデータ
	 */
	emit( event, data ) {
		if ( ! this.events[ event ] ) {
			return;
		}

		this.events[ event ].forEach( ( callback ) => {
			try {
				callback( data );
			} catch ( error ) {
				console.error(
					`Error in event listener for "${ event }":`,
					error
				);
			}
		} );
	}

	/**
	 * 1回だけ実行されるイベントリスナーを登録
	 * @param {string}   event    イベント名
	 * @param {Function} callback コールバック関数
	 */
	once( event, callback ) {
		const onceCallback = ( data ) => {
			callback( data );
			this.off( event, onceCallback );
		};
		this.on( event, onceCallback );
	}

	/**
	 * すべてのイベントリスナーをクリア
	 */
	clear() {
		this.events = {};
	}

	/**
	 * 特定のイベントのリスナーをすべて削除
	 * @param {string} event イベント名
	 */
	clearEvent( event ) {
		delete this.events[ event ];
	}
}

/**
 * イベントバスの初期化
 * @return {EventBus}
 */
export function initEventBus() {
	const eventBus = new EventBus();
	window.zenBlocks.events = eventBus;
	return eventBus;
}

/**
 * グローバルイベントバスを取得
 * @return {EventBus}
 */
export function getEventBus() {
	if ( ! window.zenBlocks.events ) {
		return initEventBus();
	}
	return window.zenBlocks.events;
}

// 標準イベント名の定義
export const EVENTS = {
	// ライセンス関連
	LICENSE_ACTIVATED: 'license:activated',
	LICENSE_DEACTIVATED: 'license:deactivated',
	LICENSE_EXPIRED: 'license:expired',
	LICENSE_UPDATED: 'license:updated',

	// ブロック関連
	BLOCK_INSERTED: 'block:inserted',
	BLOCK_REMOVED: 'block:removed',
	BLOCK_UPDATED: 'block:updated',

	// 設定関連
	SETTINGS_CHANGED: 'settings:changed',
	SETTINGS_SAVED: 'settings:saved',

	// エラー関連
	ERROR_OCCURRED: 'error:occurred',
};

export default EventBus;
