/**
 * US-17 — UI polish: dedup buttons + alignment + icons.
 * Covers AC-17.1 (single New button on EngagementsListPage)
 * and AC-17.3 (UsersAdminPage Create form alignment).
 */
import { test, expect } from '@playwright/test';
import {
  adminToken,
  createEngagement,
  deleteEngagement,
  deleteUserByUsername,
  ensureUser,
  login,
} from '../fixtures/api';
import { seedTokenInStorage } from '../fixtures/auth';

const REDTEAM_USER = 'us17-redteam';
const PASS = 'us17-pass-strong';

test.describe('US-17 — UI polish', () => {
  let redteamToken: string;
  let adminTok: string;
  let engagementId: number;

  test.beforeAll(async () => {
    adminTok = await adminToken();
    await ensureUser(REDTEAM_USER, PASS, 'redteam');
    redteamToken = (await login(REDTEAM_USER, PASS)).token;
    // Seed one engagement so the list is non-empty (EmptyState won't show extra "New" link)
    const eng = await createEngagement(redteamToken, {
      name: 'US-17 engagement',
      start_date: '2026-01-01',
    });
    engagementId = eng.id;
  });

  test.afterAll(async () => {
    try {
      const tok = await adminToken();
      await deleteEngagement(tok, engagementId);
      await deleteUserByUsername(tok, REDTEAM_USER);
    } catch {
      /* noop */
    }
  });

  test('AC-17.1 — EngagementsListPage has exactly one "New" CTA button', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, redteamToken);
    await page.goto('/engagements');
    // Wait for list to load so EmptyState doesn't briefly appear
    await page.waitForLoadState('networkidle');

    // Sprint 4: single "New" button (+ icon). Old "Create engagement" duplicate removed.
    const newButtons = page.getByRole('link', { name: /new/i });
    // Should have at least one
    await expect(newButtons.first()).toBeVisible();

    // Count all buttons/links that say "new engagement" or "create engagement"
    const newEngagementLinks = await page.getByRole('link', { name: /new/i }).count();
    const createEngagementLinks = await page.getByRole('link', { name: /create engagement/i }).count();
    const createButtons = await page.getByRole('button', { name: /create engagement/i }).count();

    // Exactly one "New" CTA — zero "Create engagement" duplicates
    expect(newEngagementLinks).toBe(1);
    expect(createEngagementLinks).toBe(0);
    expect(createButtons).toBe(0);
  });

  test('AC-17.1 — "New" button navigates to engagement creation form', async ({
    page,
    context,
  }) => {
    await seedTokenInStorage(context, redteamToken);
    await page.goto('/engagements');

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

  test('AC-17.3 — UsersAdminPage Create account form: inputs and button aligned', async ({
    page,
    context,
  }) => {
    // UsersAdminPage is admin-only
    await seedTokenInStorage(context, adminTok);
    await page.goto('/admin/users');

    // The form should be visible. Sprint 4: inputs use id="new-username" / id="new-password"
    const usernameInput = page.locator('#new-username').first();
    const passwordInput = page.locator('#new-password').first();
    const createBtn = page.getByRole('button', { name: /^create$/i }).first();

    await expect(usernameInput).toBeVisible();
    await expect(passwordInput).toBeVisible();
    await expect(createBtn).toBeVisible();

    // Alignment check via boundingBox: the 4-column grid layout puts username, password,
    // role, and button in the same row. All elements must be on the same vertical plane
    // (same y/height) and within the viewport.
    const usernameBox = await usernameInput.boundingBox();
    const passwordBox = await passwordInput.boundingBox();
    const btnBox = await createBtn.boundingBox();

    expect(usernameBox).toBeTruthy();
    expect(passwordBox).toBeTruthy();
    expect(btnBox).toBeTruthy();

    // All inputs are in separate columns — their y-positions (vertical alignment) should
    // be within one element-height of each other (same grid row).
    const yDiff = Math.abs(usernameBox!.y - passwordBox!.y);
    expect(yDiff).toBeLessThanOrEqual(usernameBox!.height + 4);

    // All elements should be visible within the viewport (not overflowing off-screen)
    const viewportWidth = page.viewportSize()!.width;
    expect(usernameBox!.x + usernameBox!.width).toBeLessThanOrEqual(viewportWidth + 4);
    expect(passwordBox!.x + passwordBox!.width).toBeLessThanOrEqual(viewportWidth + 4);
    expect(btnBox!.x + btnBox!.width).toBeLessThanOrEqual(viewportWidth + 4);

    // Username comes before password horizontally (left-to-right grid order)
    expect(usernameBox!.x).toBeLessThan(passwordBox!.x);
    // Button is positioned after the inputs (rightmost in the grid)
    expect(btnBox!.x).toBeGreaterThan(passwordBox!.x);
  });
});
