import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

type EchoInstance = Echo<'reverb'>;

declare global {
  interface Window {
    Pusher: typeof Pusher;
    Echo?: EchoInstance;
  }
}

let echoInstance: EchoInstance | null = null;

function isRealtimeConfigured(): boolean {
  return Boolean(import.meta.env.VITE_REVERB_APP_KEY);
}

export function isRealtimeEnabled(): boolean {
  return isRealtimeConfigured();
}

function getXsrfToken(): string {
  const match = document.cookie
    .split('; ')
    .find((row) => row.startsWith('XSRF-TOKEN='))
    ?.split('=')[1];

  return match ? decodeURIComponent(match) : '';
}

export function getEcho(): EchoInstance | null {
  return echoInstance;
}

let reverbSchemeMismatchLogged = false;

export function connectEcho(): EchoInstance | null {
  if (!isRealtimeConfigured()) {
    return null;
  }

  if (echoInstance) {
    return echoInstance;
  }

  const reverbScheme = import.meta.env.VITE_REVERB_SCHEME ?? 'http';
  const pageIsHttps = window.location.protocol === 'https:';
  const reverbIsHttp = reverbScheme !== 'https';

  if (pageIsHttps && reverbIsHttp) {
    if (!reverbSchemeMismatchLogged) {
      reverbSchemeMismatchLogged = true;
      console.info(
        '[mvnexus] Realtime disabled: app is HTTPS but Reverb is HTTP. Use HTTPS for Reverb or access the app over HTTP in local dev.',
      );
    }
    return null;
  }

  window.Pusher = Pusher;

  echoInstance = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST ?? window.location.hostname,
    wsPort: Number(import.meta.env.VITE_REVERB_PORT ?? 8080),
    wssPort: Number(import.meta.env.VITE_REVERB_PORT ?? 443),
    forceTLS: reverbScheme === 'https',
    enabledTransports: ['ws', 'wss'],
    authEndpoint: '/api/v1/broadcasting/auth',
    auth: {
      headers: {
        'X-XSRF-TOKEN': getXsrfToken(),
        Accept: 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
      },
    },
  });

  window.Echo = echoInstance;

  const connection = echoInstance.connector?.pusher?.connection;
  if (connection) {
    connection.bind('disconnected', () => {
      console.warn('[mvnexus] Realtime disconnected — live updates may be delayed.');
      window.dispatchEvent(new CustomEvent('mvhd:realtime-disconnected'));
    });
    connection.bind('unavailable', () => {
      console.warn('[mvnexus] Realtime unavailable — check Reverb/WebSocket connectivity.');
      window.dispatchEvent(new CustomEvent('mvhd:realtime-unavailable'));
    });
  }

  return echoInstance;
}

export function disconnectEcho(): void {
  if (echoInstance) {
    echoInstance.disconnect();
    echoInstance = null;
  }

  if (window.Echo) {
    delete window.Echo;
  }
}

export function leaveChannel(channelName: string): void {
  if (!echoInstance) {
    return;
  }

  echoInstance.leave(channelName);
}
