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

/**
 * Plan 03 alerting smoke suite.
 *
 * Covers the CRUD + navigation paths that don't require event injection:
 *   - sidebar → inbox
 *   - create + delete a rule via the 5-step wizard
 *   - CMD-K opens, closes cleanly
 *   - silence create + end-early
 *
 * End-to-end fire→ack→clear is covered server-side by `AlertingFullLifecycleIT`
 * (Plan 02). Exercising it from the UI would require injecting executions
 * into ClickHouse, which is out of scope for this smoke.
 *
 * Note: the design-system `SectionHeader` renders a generic element (not role=heading),
 * so page headings are asserted via `getByText`.
 */

test.describe('alerting UI smoke', () => {
  test('sidebar Alerts section navigates to inbox', async ({ page }) => {
    // Click the Alerts sidebar section header. On navigation the accordion
    // will already be expanded; the "Alerts" label is on the toggle button.
    await page.getByRole('button', { name: /^(collapse|expand) alerts$/i }).first().click();
    await expect(page).toHaveURL(/\/alerts\/inbox/, { timeout: 10_000 });
    // Inbox page renders "Inbox" text + "Mark all read" button.
    await expect(page.getByText(/^Inbox$/)).toBeVisible();
    await expect(page.getByRole('button', { name: /mark all read/i })).toBeVisible();
  });

  test('create + delete a rule via the wizard', async ({ page }) => {
    // Unique name per run so leftover rules from crashed prior runs don't
    // trip the strict-mode "multiple matches" check.
    const ruleName = `e2e smoke rule ${Date.now()}`;

    await page.goto('/alerts/rules');
    await expect(page.getByText(/^Alert rules$/)).toBeVisible();

    await page.getByRole('link', { name: /new rule/i }).click();
    await expect(page).toHaveURL(/\/alerts\/rules\/new/);

    // Step 1 — Scope. DS FormField renders the label as a generic element
    // (not `htmlFor` wired), so the textbox's accessible name is its placeholder.
    await page.getByPlaceholder('Order API error rate').fill(ruleName);
    await page.getByRole('button', { name: /^next$/i }).click();

    // Step 2 — Condition (leave at ROUTE_METRIC default)
    await page.getByRole('button', { name: /^next$/i }).click();

    // Step 3 — Trigger (defaults)
    await page.getByRole('button', { name: /^next$/i }).click();

    // Step 4 — Notify: default title/message templates are pre-populated;
    // targets/webhooks empty is OK for smoke.
    await page.getByRole('button', { name: /^next$/i }).click();

    // Step 5 — Review + save
    await page.getByRole('button', { name: /^create rule$/i }).click();

    // Land on rules list, rule appears in the table.
    await expect(page).toHaveURL(/\/alerts\/rules$/, { timeout: 10_000 });
    const main = page.locator('main');
    await expect(main.getByRole('link', { name: ruleName })).toBeVisible({ timeout: 10_000 });

    // Cleanup: open ConfirmDialog via row Delete button, confirm in dialog.
    await page
      .getByRole('row', { name: new RegExp(ruleName) })
      .getByRole('button', { name: /^delete$/i })
      .click();
    const confirmDelete = page.getByRole('dialog');
    await expect(confirmDelete.getByText(/delete alert rule/i)).toBeVisible();
    await confirmDelete.getByRole('button', { name: /^delete$/i }).click();
    await expect(main.getByRole('link', { name: ruleName })).toHaveCount(0);
  });

  test('CMD-K palette opens + closes', async ({ page }) => {
    await page.goto('/alerts/inbox');
    // The DS CommandPalette is toggled by the SearchTrigger button in the top bar
    // (accessible name "Open search"). Ctrl/Cmd+K is wired inside the DS but
    // clicking the button is the deterministic path.
    await page.getByRole('button', { name: /open search/i }).click();
    const dialog = page.getByRole('dialog').first();
    await expect(dialog).toBeVisible({ timeout: 5_000 });
    await page.keyboard.press('Escape');
    await expect(dialog).toBeHidden();
  });

  test('silence create + end-early', async ({ page }) => {
    await page.goto('/alerts/silences');
    await expect(page.getByText(/^Alert silences$/)).toBeVisible();

    const unique = `smoke-app-${Date.now()}`;
    // DS FormField labels aren't `htmlFor`-wired, so target via parent-of-label → textbox.
    const form = page.locator('main');
    await form.getByText(/^App slug/).locator('..').getByRole('textbox').fill(unique);
    await form.getByRole('spinbutton').fill('1');
    await form.getByPlaceholder('Maintenance window').fill('e2e smoke');
    await page.getByRole('button', { name: /create silence/i }).click();

    await expect(page.getByText(unique).first()).toBeVisible({ timeout: 10_000 });

    await page
      .getByRole('row', { name: new RegExp(unique) })
      .getByRole('button', { name: /^end early$/i })
      .click();
    const confirmEnd = page.getByRole('dialog');
    await expect(confirmEnd.getByText(/end silence/i)).toBeVisible();
    await confirmEnd.getByRole('button', { name: /end silence/i }).click();
    await expect(page.getByText(unique)).toHaveCount(0);
  });
});
