// [TSM.ID].[11031972] -- All Rights Reserved. Proprietary & Confidential.
export type SocketCallback = (data: unknown) => void;

/// XCU Media over QUIC (MoQ) / WebSocket Adapter
/// Menggantikan `ZeroSocket` dan `Socket.IO`
/// Fitur:
/// - Terhubung langsung ke mesin Rust (`xcu-neural-chat`) di port 8443
/// - Tidak menggunakan Redis PubSub
/// - Berjalan via WebSocket (fallback untuk WebTransport tanpa HTTPS certs)
export class XcuMoq {
  private url: string;
  private listeners: Record<string, SocketCallback[]> = {};
  private ws: WebSocket | null = null;
  public id: string;
  private reconnectTimer: any;

  constructor(url: string) {
    this.url = url;
    this.id = Math.random().toString(36).substring(2, 15);
  }

  connect() {
    if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) return;
    
    // Sambungkan langsung ke Alpha VPS atau localhost
    let wsUrl = "ws://160.187.143.253:8443";
    if (typeof window !== "undefined" && window.location.hostname === "localhost") {
      wsUrl = "ws://127.0.0.1:8443";
    }

    try {
      this.ws = new WebSocket(wsUrl);

      this.ws.onopen = () => {
        console.log("[XCU MoQ] Terhubung ke Neural Mesh Rust Engine.");
        if (this.listeners["connect"]) {
          this.listeners["connect"].forEach(fn => fn({}));
        }
      };

      this.ws.onmessage = (e) => {
        try {
          const data = JSON.parse(e.data);
          if (data.event && this.listeners[data.event]) {
            this.listeners[data.event].forEach(fn => fn(data.payload));
          }
        } catch {
          // Abaikan parse error
        }
      };

      this.ws.onclose = () => {
        console.warn("[XCU MoQ] Koneksi terputus. Neural link lost.");
        if (this.listeners["disconnect"]) {
          this.listeners["disconnect"].forEach(fn => fn({}));
        }
        // Auto-reconnect
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = setTimeout(() => this.connect(), 3000);
      };

      this.ws.onerror = (err) => {
        console.error("[XCU MoQ] WebSocket Error:", err);
      };
    } catch (e) {
      console.error("[XCU MoQ] Gagal inisialisasi:", e);
    }
  }

  on(event: string, callback: SocketCallback) {
    if (!this.listeners[event]) this.listeners[event] = [];
    this.listeners[event].push(callback);
    return this;
  }
  
  once(event: string, callback: SocketCallback) {
    const onceWrapper = (data: unknown) => {
        callback(data);
        this.off(event, onceWrapper);
    };
    this.on(event, onceWrapper);
    return this;
  }

  off(event: string, callback?: SocketCallback) {
    if (!this.listeners[event]) return this;
    if (callback) {
        this.listeners[event] = this.listeners[event].filter(cb => cb !== callback);
    } else {
        delete this.listeners[event];
    }
    return this;
  }

  emit(event: string, payload: string | Record<string, unknown> = {}) {
    const normalizedPayload = typeof payload === 'string' ? { value: payload } : payload;
    
    // Kirim pesan ke mesin Rust via WebSocket
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      const msg = JSON.stringify({
        client_id: this.id,
        event,
        payload: normalizedPayload
      });
      this.ws.send(msg);
    } else {
      console.warn("[XCU MoQ] Pesan di-drop: Tidak terhubung ke Neural Mesh.");
    }
    
    return this;
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    clearTimeout(this.reconnectTimer);
  }
}

export const io = (url?: string, options?: any) => {
  const socket = new XcuMoq(url || "");
  socket.connect();
  return socket; 
};

export type Socket = XcuMoq;
