/**
 * Tests for Gateway WebSocket Client (Browser version)
 */

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { GatewayClient } from '../../desktop/src/lib/gateway-client';

describe('GatewayClient', () => {
  let client: GatewayClient;
  let mockWs: any;

  beforeEach(() => {
    client = new GatewayClient({
      url: 'ws://localhost:18790',
      token: '',
      autoReconnect: false,
      requestTimeout: 5000,
    });
  });

  afterEach(() => {
    client.disconnect();
  });

  describe('constructor', () => {
    it('should initialize with default options', () => {
    const defaultClient = new GatewayClient();
    expect(defaultClient.getState()).toBe('disconnected');
  });

    it('should initialize with custom options', () => {
    const customClient = new GatewayClient({
      url: 'ws://custom:1234',
      token: 'test-token',
      autoReconnect: false,
    });
    expect(customClient.getState()).toBe('disconnected');
  });
  });

  describe('connection state', () => {
    it('should start in disconnected state', () => {
    expect(client.getState()).toBe('disconnected');
  });

  it('should emit state changes', () => {
    const stateChanges: string[] = [];
    client.onStateChange = (state) => {
      stateChanges.push(state);
    };

    // Note: actual connection requires a real WebSocket server
    // This test verifies the callback mechanism
    expect(typeof client.onStateChange).toBe('function');
  });
  });

  describe('event subscription', () => {
    it('should allow subscribing to events', () => {
    const callback = vi.fn();
    const unsubscribe = client.on('test', callback);

    // Verify unsubscribe is a function
    expect(typeof unsubscribe).toBe('function');
  });

    it('should allow multiple listeners for same event', () => {
    const callback1 = vi.fn();
    const callback2 = vi.fn();

    client.on('test', callback1);
    client.on('test', callback2);

    // Both listeners should be registered
    // (In real scenario, they would be called when event is emitted)
  });
  });

  describe('agent stream subscription', () => {
    it('should provide onAgentStream helper', () => {
    const callback = vi.fn();
    const unsubscribe = client.onAgentStream(callback);

    expect(typeof unsubscribe).toBe('function');
  });
  });

  describe('disconnect', () => {
    it('should cleanup resources on disconnect', () => {
    client.disconnect();
    expect(client.getState()).toBe('disconnected');
  });
  });

  describe('API methods', () => {
    it('should have chat method', () => {
    expect(typeof client.chat).toBe('function');
  });

    it('should have health method', () => {
    expect(typeof client.health).toBe('function');
  });

    it('should have status method', () => {
    expect(typeof client.status).toBe('function');
  });

    it('should have ZCLAW custom methods', () => {
    expect(typeof client.listClones).toBe('function');
    expect(typeof client.createClone).toBe('function');
    expect(typeof client.getUsageStats).toBe('function');
    expect(typeof client.getPluginStatus).toBe('function');
  });
  });
});
