import { expect, test } from '@playwright/test';
import { loginToDashboard } from './fixtures';

const OFFLINE_AGENT = {
  id: 'e2e-offline-agent',
  name: 'Offline Node',
  wallet: '4' + 'A'.repeat(94),
  ip: '192.168.1.99',
  version: '1.0.0',
  status: 'offline',
  cpu_cores: 4,
  memory_gb: 8,
  last_seen: new Date(Date.now() - 3600_000).toISOString(),
  created_at: new Date().toISOString(),
  hashrate_15s: 0,
  hashrate_1m: 0,
  hashrate_15m: 0,
  shares_total: 0,
  shares_good: 0,
  shares_bad: 0,
  cpu_usage_pct: 0,
  memory_usage_pct: 0,
  uptime_seconds: 0,
  platform: 'windows',
  arch: 'amd64',
};

test.describe('Remote actions UI', () => {
  test.beforeEach(async ({ page }) => {
    // AgentsPage syncs from WebSocket when connected; mock dashboard WS init (HTTP route cannot intercept WS).
    await page.addInitScript((agent) => {
      const RealWS = WebSocket;
      const g = globalThis as typeof globalThis & { __afRealWebSocket?: typeof WebSocket };
      g.__afRealWebSocket = RealWS;
      globalThis.WebSocket = function (url: string | URL, protocols?: string | string[]) {
        const urlStr = String(url);
        if (!urlStr.includes('/ws/dashboard')) {
          return new g.__afRealWebSocket!(url, protocols);
        }
        let openHandler: (() => void) | null = null;
        let messageHandler: ((ev: MessageEvent) => void) | null = null;
        let closeHandler: (() => void) | null = null;
        const sock = {
          readyState: 0,
          send() {},
          close() {
            sock.readyState = 3;
            closeHandler?.();
          },
          set onopen(fn: (() => void) | null) {
            openHandler = fn;
          },
          get onopen() {
            return openHandler;
          },
          set onmessage(fn: ((ev: MessageEvent) => void) | null) {
            messageHandler = fn;
          },
          get onmessage() {
            return messageHandler;
          },
          set onclose(fn: (() => void) | null) {
            closeHandler = fn;
          },
          get onclose() {
            return closeHandler;
          },
          set onerror(_fn: (() => void) | null) {},
          get onerror() {
            return null;
          },
        };
        queueMicrotask(() => {
          sock.readyState = 1;
          openHandler?.();
          messageHandler?.({
            data: JSON.stringify({ type: 'init', payload: { agents: [agent] } }),
          } as MessageEvent);
        });
        return sock as unknown as WebSocket;
      } as unknown as typeof WebSocket;
      globalThis.WebSocket.OPEN = 1;
      globalThis.WebSocket.CONNECTING = 0;
      globalThis.WebSocket.CLOSED = 3;
    }, OFFLINE_AGENT);
    await page.route(/\/api\/v1\/agents$/, async (route) => {
      if (route.request().method() !== 'GET') {
        await route.continue();
        return;
      }
      await route.fulfill({ json: [OFFLINE_AGENT] });
    });
    await page.route('**/api/v1/agents/*/stats*', async (route) => {
      await route.fulfill({ json: [] });
    });
    await page.route('**/api/v1/builds', async (route) => {
      await route.fulfill({ json: [] });
    });
    await page.route('**/api/v1/server/info', async (route) => {
      await route.fulfill({
        json: {
          version: 'test',
          suggested_url: 'http://127.0.0.1:8989',
          agent_count: 1,
          online_count: 0,
        },
      });
    });
    await loginToDashboard(page);
    await page.getByRole('link', { name: /Fleet Roster/i }).click();
    await expect(page.getByRole('heading', { name: 'Fleet Roster' })).toBeVisible({ timeout: 10_000 });
    await expect(page.getByText('Offline Node')).toBeVisible({ timeout: 10_000 });
  });

  test('detail panel disables remote actions for offline agent', async ({ page }) => {
    await page.getByText('Offline Node').click();
    const detail = page.locator('.agent-detail');
    await expect(detail.getByRole('heading', { name: 'Remote Control' })).toBeVisible({ timeout: 10_000 });
    await expect(detail.getByRole('button', { name: 'Screenshot' })).toBeDisabled();
    await expect(detail.getByRole('button', { name: 'Pause' })).toBeDisabled();
  });

  test('compact row remote actions disabled when offline', async ({ page }) => {
    await page.getByText('Offline Node').click();
    const compact = page.locator('.agent-list-item.expanded');
    await expect(compact.getByRole('button', { name: 'Pause' })).toBeDisabled();
  });
});
