import { test, expect } from '../../fixtures.js';
import { MailpitClient } from '../../helpers/mailpit.js';

test.describe('Magic Link Authentication', () => {
  const mailpit = new MailpitClient();
  const testEmail = `test-student-${Date.now()}@e2e.local`;

  test.beforeEach(({ features }) => {
    test.skip(!features.students, 'Students feature not enabled');
  });

  test('request magic link, receive email, verify token, get session', async ({
    browser,
    customerConfig,
    customerName,
  }) => {
    await mailpit.deleteAllEmails();

    // Use a fresh context without auth for student login
    const context = await browser.newContext({
      baseURL: customerConfig.url,
      ignoreHTTPSErrors: true,
    });
    const page = await context.newPage();

    try {
      // 1. Request magic link via API
      const requestUrl = new URL(
        '/api/actions/auth/magic-link/request',
        customerConfig.url
      );
      requestUrl.searchParams.set('redirect_uri', customerConfig.url);
      requestUrl.searchParams.set('customer', customerName);

      const requestResponse = await fetch(requestUrl.toString(), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: testEmail }),
      });

      expect(requestResponse.status).toBe(200);

      // 2. Wait for email to arrive in Mailpit
      const email = await mailpit.waitForEmail(testEmail, 15_000);
      expect(email).toBeTruthy();
      expect(email.Subject).toBeTruthy();

      // 3. Get full email body and extract magic link
      const emailDetail = await mailpit.getEmailBody(email.ID);
      const magicLinkUrl = mailpit.extractMagicLinkUrl(emailDetail.HTML);
      expect(magicLinkUrl).toContain('/students/verify');
      expect(magicLinkUrl).toContain('token=');

      // 4. Navigate to magic link URL in browser
      await page.goto(magicLinkUrl);

      // 5. Should end up on students page with active session
      await expect(page).toHaveURL(/\/students/, { timeout: 15_000 });

      // 6. Verify session is active
      await expect(page.locator('body')).toBeVisible();
    } finally {
      await context.close();
    }
  });

  test('invalid token returns error', async ({ customerConfig, customerName }) => {
    const verifyResponse = await fetch(
      `${customerConfig.url}/api/actions/auth/magic-link/verify`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          token: 'invalid-token-12345',
          customer: customerName,
        }),
      }
    );

    expect(verifyResponse.status).toBe(401);
    const body = await verifyResponse.json();
    expect(body.error).toBeTruthy();
  });
});
