import { MFEEvent, MFEEventType } from '@ready/shared-types';

const EVENT_NAME = 'READY_MFE_EVENT';

/**
 * Dispatch an event across MFEs in the current window and across tabs via BroadcastChannel.
 */
export function emitMFEEvent<T = any>(type: MFEEventType, payload?: T) {
  if (typeof window === 'undefined') return;

  const eventDetail: MFEEvent<T> = { type, payload };

  // Dispatch standard window event
  window.dispatchEvent(new CustomEvent(EVENT_NAME, { detail: eventDetail }));

  // Dispatch via BroadcastChannel for multi-tab synchronization
  try {
    if ('BroadcastChannel' in window) {
      const channel = new BroadcastChannel('ready_platform_channel');
      channel.postMessage(eventDetail);
      channel.close();
    }
  } catch (e) {
    // Graceful fallback if BroadcastChannel is blocked
  }
}

/**
 * Subscribe to MFE platform events.
 * Returns an unsubscribe callback.
 */
export function subscribeMFEEvent(callback: (event: MFEEvent) => void): () => void {
  if (typeof window === 'undefined') {
    return () => {};
  }

  const handleCustomEvent = (e: Event) => {
    const customEvt = e as CustomEvent<MFEEvent>;
    if (customEvt.detail) {
      callback(customEvt.detail);
    }
  };

  window.addEventListener(EVENT_NAME, handleCustomEvent);

  let channel: BroadcastChannel | null = null;
  if ('BroadcastChannel' in window) {
    try {
      channel = new BroadcastChannel('ready_platform_channel');
      channel.onmessage = (messageEvent) => {
        if (messageEvent.data) {
          callback(messageEvent.data);
        }
      };
    } catch (e) {}
  }

  return () => {
    window.removeEventListener(EVENT_NAME, handleCustomEvent);
    if (channel) {
      channel.close();
    }
  };
}

/**
 * Check if a given remote service is reachable.
 */
export async function checkServiceHealth(url: string, timeoutMs: number = 3000): Promise<boolean> {
  try {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeoutMs);
    const response = await fetch(url, {
      method: 'HEAD',
      mode: 'no-cors',
      signal: controller.signal,
    });
    clearTimeout(timer);
    return true;
  } catch (e) {
    return false;
  }
}
