/**
 * E2E — Invite flow
 *
 * Requires:
 *  - Dev server running on http://localhost:3100
 *  - Mailhog running on http://localhost:8025
 *  - SMTP_HOST=localhost, SMTP_PORT=1025, SMTP_TLS=false configured
 *
 * Flow:
 *  1. Admin opens /admin/users → clicks "Invite User"
 *  2. Fills in a unique test email address + role USER
 *  3. Waits for "Invitation sent successfully." message in modal
 *  4. Reads the invite email from Mailhog
 *  5. Visits the invite link in a separate page context
 *  6. Sets a password → account created
 *  7. Signs in with the new credentials → lands on dashboard
 */
import { expect, test } from "@playwright/test";
import { STORAGE_STATE } from "../../playwright.dev.config.js";
import { clearMailhog, extractUrlFromEmail, getLatestEmailTo } from "./helpers.js";

test.describe("invite flow", () => {
  test.use({ storageState: STORAGE_STATE.admin });

  test.beforeEach(async () => {
    await clearMailhog();
  });

  test("admin invites a new user and invited user can sign in", async ({ page, browser }) => {
    const testEmail = `invite-e2e-${Date.now()}@capakraken.test`;

    // Step 1: Navigate to admin users page
    await page.goto("/admin/users");
    await page.waitForLoadState("networkidle");

    // Step 2: Open invite modal
    await page.click('button:has-text("Invite User")');
    // Wait for the modal heading — AnimatedModal does not use role="dialog"
    await page.waitForSelector('text=Invite User', { state: "visible" });

    // Step 3: Fill in invite form
    await page.fill('input[type="email"]', testEmail);

    // Step 4: Submit
    await page.click('button:has-text("Send Invite")');

    // Step 5: Wait for success message (exact text from InviteUserModal.tsx)
    await expect(page.locator("text=Invitation sent successfully.")).toBeVisible({ timeout: 10_000 });

    // Step 6: Read invite email from Mailhog
    const email = await getLatestEmailTo(testEmail, { timeoutMs: 15_000 });
    const inviteUrl = extractUrlFromEmail(email, "/invite/");

    // Strip base URL — Playwright navigates relative to baseURL
    const invitePath = new URL(inviteUrl).pathname;

    // Step 7: Accept invite in a fresh unauthenticated context (no admin cookies)
    const inviteContext = await browser.newContext();
    const invitePage = await inviteContext.newPage();
    await invitePage.goto(`http://localhost:3100${invitePath}`);

    // Wait for the accept-invite form
    await expect(invitePage.locator("text=Accept invitation")).toBeVisible({ timeout: 10_000 });

    // Fill both password fields using consistent nth() indexing
    const passwordInputs = invitePage.locator('input[type="password"]');
    await passwordInputs.nth(0).fill("TestPass123!");
    await passwordInputs.nth(1).fill("TestPass123!");
    await invitePage.click('button[type="submit"]');

    // Account created confirmation
    await expect(invitePage.locator("text=Account created")).toBeVisible({ timeout: 15_000 });

    // Step 8: Sign in with new credentials
    await invitePage.click('button:has-text("Go to sign in")');
    await invitePage.waitForURL(/\/auth\/signin/);

    await invitePage.fill('input[type="email"]', testEmail);
    await invitePage.fill('input[type="password"]', "TestPass123!");
    await invitePage.click('button[type="submit"]');

    await invitePage.waitForURL(/\/(dashboard|resources)/, { timeout: 15_000 });
    await inviteContext.close();
  });
});
