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

const adminUser = {
  id: 'user-1',
  email: 'admin@example.test',
  role: 'admin',
  plan: 'internal',
  displayName: 'Dashboard Admin',
  emailVerified: true,
  currentProduct: 'bytelyst-devops',
  products: [{ productId: 'bytelyst-devops', plan: 'internal', role: 'admin' }],
  mfaEnabled: false,
  mfaMethods: [],
};

// /hermes mounts <HermesOpsPanel>, which calls api.getHermesOps() against the
// backend's `/api/hermes/ops` endpoint. The backend shells out to systemctl /
// git / ps / du on the live VM and is therefore neither available nor
// deterministic in CI. We intercept the fetch with a fixture snapshot so the
// E2E suite can run against the web stack alone.
// Shape mirrors `HermesOpsSnapshot` in `web/src/lib/api.ts` (which mirrors the
// backend Zod schema in `backend/src/modules/hermes-ops/types.ts`). Empty
// `quickLinks`/`instances` arrays are deliberate — the panel is only required
// to render without throwing in CI; the mission-control overview is what the
// suite actually asserts on.
const hermesOpsSnapshot = {
  generatedAt: '2026-01-01T00:00:00.000Z',
  tailscaleIp: '100.0.0.1',
  emergencyDriveUpload: {
    name: 'hermes-emergency-drive-upload.timer',
    active: false,
    nextRun: null,
    lastRun: null,
  },
  activeSessions: { active: 0, updatedAt: '2026-01-01T00:00:00.000Z' },
  cronJobs: [],
  recentAlerts: [],
  quickLinks: [],
  instances: [],
  warnings: [],
};

const hermesTelemetrySnapshot = (instanceId: 'vijay' | 'bheem') => ({
  generatedAt: '2026-01-01T00:00:00.000Z',
  cached: false,
  instanceId,
  sessions: { totalSessions: instanceId === 'vijay' ? 12 : 7, totalMessages: instanceId === 'vijay' ? 480 : 210, status: 'up' },
  sessionList: {
    status: 'up',
    entries: [
      {
        id: `${instanceId}-session-1`,
        sessionKey: `agent:main:telegram:dm:${instanceId}`,
        platform: 'telegram',
        chatType: 'dm',
        displayName: instanceId === 'vijay' ? 'S' : 'Uma',
        createdAt: '2026-01-01T00:00:00.000Z',
        updatedAt: '2026-01-01T00:06:00.000Z',
        suspended: false,
        resumePending: false,
        totalTokens: 100,
        estimatedCostUsd: 0,
      },
    ],
  },
  sessionEvents: {
    status: 'up',
    sourceCount: 1,
    entries: [
      {
        id: `${instanceId}-events.jsonl:3`,
        sessionFile: `${instanceId}-events.jsonl`,
        timestamp: '2026-01-01T00:06:00.000Z',
        role: 'assistant',
        eventType: 'tool-call',
        summary: 'assistant tool call: exec_command',
        toolNames: ['exec_command'],
        itemTypes: [],
        status: 'tool_calls',
      },
    ],
  },
  cron: {
    status: 'up',
    entries: [
      {
        id: `${instanceId}-digest`,
        name: `${instanceId} digest`,
        schedule: '0 * * * *',
        lastRun: '2026-01-01T00:00:00.000Z',
        nextRun: '2026-01-01T01:00:00.000Z',
        lastStatus: 'ok',
        active: true,
      },
    ],
  },
  memory: { status: 'up', items: [] },
  skills: { status: 'up', items: [] },
  watchdog: {
    source: `/tmp/${instanceId}-watchdog.log`,
    status: 'up',
    alerts: [
      {
        timestamp: '2026-01-01T00:05:00.000Z',
        severity: 'info',
        message: `${instanceId} watchdog healthy`,
      },
    ],
  },
  backupHistory: {
    repoPath: `/tmp/${instanceId}-repo`,
    status: 'up',
    entries: [
      {
        sha: `${instanceId}123456`,
        committedAt: '2026-01-01T00:03:00.000Z',
        subject: `${instanceId} backup`,
      },
    ],
  },
  warnings: [],
});

test.describe('Hermes Mission Control', () => {
  test.beforeEach(async ({ page }) => {
    await page.addInitScript(() => {
      window.localStorage.setItem('access_token', 'e2e-access-token');
      window.localStorage.setItem('refresh_token', 'e2e-refresh-token');
    });

    await page.route('**/auth/me', async (route) => {
      await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(adminUser) });
    });

    await page.route('**/api/hermes/ops', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(hermesOpsSnapshot),
      });
    });

    await page.route('**/api/hermes/telemetry/vijay', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(hermesTelemetrySnapshot('vijay')),
      });
    });

    await page.route('**/api/hermes/telemetry/bheem', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(hermesTelemetrySnapshot('bheem')),
      });
    });

    // /hermes/products fetches the real service registry + health module
    // (Phase 3 slice 2). Backend isn't running in CI, so we satisfy those
    // routes the same way the dashboard spec does.
    await page.route('**/api/services', async (route) => {
      await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify([]) });
    });
    await page.route('**/api/health', async (route) => {
      await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify([]) });
    });
    await page.route('**/api/health/cache', async (route) => {
      await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ message: 'Cache cleared' }) });
    });
  });

  test('renders the mission control overview and navigates to companion views', async ({ page }) => {
    await page.goto('/hermes');
    await expect(page.getByRole('heading', { name: 'Hermes Mission Control' })).toBeVisible();
    await expect(page.getByText('Active Missions')).toBeVisible();
    await expect(page.getByText('Founder Attention Queue')).toBeVisible();
    await expect(page.getByRole('heading', { name: 'Product Health Snapshot' })).toBeVisible();

    await page.getByRole('link', { name: 'Task Ledger' }).click();
    await expect(page.getByRole('heading', { name: 'Task Ledger' })).toBeVisible();
    await expect(page.getByRole('heading', { name: 'Task table' })).toBeVisible();

    await page.goto('/hermes/tasks/task-1');
    await expect(page.getByRole('heading', { name: 'Hermes learning' })).toBeVisible();
    await expect(page.getByRole('heading', { name: 'Timeline', exact: true })).toBeVisible();

    await page.goto('/hermes/products');
    await expect(page.getByRole('heading', { name: 'Product Portfolio' })).toBeVisible();

    await page.goto('/hermes/history');
    await expect(page.getByRole('heading', { name: 'Historical Activity' })).toBeVisible();

    await page.goto('/hermes/agents');
    await expect(page.getByRole('heading', { name: 'Agent & Tool Observability' })).toBeVisible();

    await page.goto('/hermes/settings');
    await expect(page.getByRole('heading', { name: 'Settings & Configuration' })).toBeVisible();
  });

  test('renders the mission control overview at mobile width', async ({ page }) => {
    await page.setViewportSize({ width: 390, height: 844 });

    await page.goto('/hermes');
    await expect(page.getByRole('heading', { name: 'Hermes Mission Control' })).toBeVisible();
    await expect(page.getByRole('link', { name: 'Task Ledger' })).toBeVisible();
    await expect(page.getByRole('link', { name: 'Product Portfolio' })).toBeVisible();

    await page.goto('/hermes/tasks/task-1');
    await expect(page.getByRole('heading', { name: 'Hermes learning' })).toBeVisible();
    await expect(page.getByRole('heading', { name: 'Timeline', exact: true })).toBeVisible();
  });

  test('exposes a global instance switcher with All / Vijay / Bheem', async ({ page }) => {
    await page.goto('/hermes');
    const switcher = page.getByRole('radiogroup', { name: 'Hermes instance filter' });
    await expect(switcher).toBeVisible();

    // Default selection persists across navigation; "All" should be the
    // active option on first visit (no localStorage entry yet).
    await expect(switcher.getByRole('radio', { name: 'All' })).toHaveAttribute('aria-checked', 'true');

    // Per-instance roll-up section should always be visible regardless of filter.
    await expect(page.getByRole('heading', { name: 'Per-instance roll-up' })).toBeVisible();

    // Switching to Bheem should still keep the page rendering correctly.
    await switcher.getByRole('radio', { name: 'Bheem (uma)' }).click();
    await expect(switcher.getByRole('radio', { name: 'Bheem (uma)' })).toHaveAttribute('aria-checked', 'true');
    await expect(page.getByRole('heading', { name: 'Hermes Mission Control' })).toBeVisible();
  });
});
