import { test, expect } from '@playwright/test';
import {
  Applicant,
  newApplicant,
  signUp,
  verifyOtpIfPrompted,
} from './support/applicant';
import { deleteApplicant, sql } from './support/db';

/**
 * Signing up, and being asked what you operate as before anything else.
 *
 * The gate is the whole point: the catalogue is filtered by the answer and the
 * API refuses an application for a mode the profile does not hold, so an
 * applicant who skipped this would reach a dashboard that offers them nothing
 * and explains nothing.
 */
test.describe('signup and onboarding', () => {
  let applicant: Applicant;

  test.beforeEach(() => {
    applicant = newApplicant('onboard');
  });

  test.afterEach(() => {
    deleteApplicant(applicant.email);
  });

  test('a new applicant is asked for their operations before reaching the dashboard', async ({
    page,
  }) => {
    const offset = await signUp(page, applicant);
    await verifyOtpIfPrompted(page, offset);

    // The account exists in IAM ...
    const rows = sql(
      `SELECT email FROM iam.users WHERE email = '${applicant.email}'`,
    );
    expect(rows).toHaveLength(1);

    // ... and the first thing behind the session is the question, not the app.
    await expect(page).toHaveURL(/\/onboarding\/operations/, { timeout: 30_000 });
    await expect(
      page.getByRole('heading', { name: /what do you operate as/i }),
    ).toBeVisible();

    // The dashboard stays out of reach until it is answered.
    await page.goto('/dashboard');
    await expect(page).toHaveURL(/\/onboarding\/operations/);

    // Answer it.
    await page
      .getByRole('checkbox', { name: /freight forwarder license/i })
      .first()
      .check();
    await page.getByRole('button', { name: /save operations/i }).click();

    await expect(page).toHaveURL(/\/dashboard/, { timeout: 30_000 });

    // And it stuck: stored against the profile, keyed by the IAM user id.
    const declared = sql(`
      SELECT lt.key
      FROM profile_operator_types pot
      JOIN profiles p ON p.id = pot.profile_id
      JOIN iam.users u ON u.id = p.user_id
      JOIN license_types lt ON lt.id = pot.license_type_id
      WHERE u.email = '${applicant.email}' AND pot.deleted_at IS NULL
    `);
    expect(declared.map((r) => r[0])).toEqual(['FREIGHT_FORWARDER']);
  });

  test('the dashboard leads with a get-started panel when there is nothing to show', async ({
    page,
  }) => {
    const offset = await signUp(page, applicant);
    await verifyOtpIfPrompted(page, offset);
    await expect(page).toHaveURL(/\/onboarding\/operations/, { timeout: 30_000 });

    await page
      .getByRole('checkbox', { name: /freight forwarder license/i })
      .first()
      .check();
    await page.getByRole('button', { name: /save operations/i }).click();
    await expect(page).toHaveURL(/\/dashboard/, { timeout: 30_000 });

    // Nothing filed and nothing held: one panel, not two empty sections.
    await expect(page.getByRole('heading', { name: 'Get started' })).toBeVisible();
    await expect(
      page.getByRole('heading', { name: 'My applications' }),
    ).toHaveCount(0);
    await expect(page.getByRole('heading', { name: 'My licences' })).toHaveCount(
      0,
    );

    // The catalogue is directly beneath it, filtered to what they declared.
    await expect(
      page.getByRole('heading', { name: /apply for a licence/i }),
    ).toBeVisible();
    await expect(page.getByText('Freight Forwarder License').first()).toBeVisible();
    await expect(page.getByText('Shipping Agent License')).toHaveCount(0);
  });
});
