import { test, expectFixture as expect } from '../helpers/test-fixtures';

const shouldRun = process.env.E2E_TESTING_API === '1';

test.describe('Standard package checkout with Paddle completion', () => {
  test.skip(!shouldRun, 'Set E2E_TESTING_API=1 to enable checkout tests that use /api/_testing endpoints.');
  test('registers, applies coupon, and reaches confirmation', async ({
    page,
    clearTestMailbox,
    seedTestCoupons,
    getLatestCheckoutSession,
    simulatePaddleCompletion,
    getTestMailbox,
  }) => {
    await clearTestMailbox();
    await seedTestCoupons();

    const unique = Date.now();
    const email = `checkout+${unique}@example.test`;
    const password = 'Password123!';
    await page.addInitScript(() => {
      window.__openedWindows = [];
      const originalOpen = window.open;
      window.open = function (...args) {
        window.__openedWindows.push(args);
        return originalOpen?.apply(this, args) ?? null;
      };
    });

    await page.route('https://cdn.paddle.com/paddle/v2/paddle.js', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/javascript',
        body: `
          window.__paddleEventCallback = null;
          window.__paddleInitOptions = null;
          window.__paddleCheckoutConfig = null;
          window.Paddle = {
            Environment: { set() {} },
            Initialize(options) {
              window.__paddleInitOptions = options;
              window.__paddleEventCallback = options?.eventCallback || null;
            },
            Checkout: {
              open(config) {
                window.__paddleCheckoutConfig = config;
              },
            },
          };
        `,
      });
    });

    let paddleRequestPayload: Record<string, unknown> | null = null;
    await page.route('**/paddle/create-checkout', async (route) => {
      paddleRequestPayload = route.request().postDataJSON() as Record<string, unknown>;
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          checkout_url: 'https://sandbox.paddle.test/checkout/abc123',
        }),
      });
    });

    await page.goto('/de/packages');

    const standardDetailsButton = page
      .locator('[data-slot="card"]')
      .filter({ hasText: /Standard/i })
      .getByRole('button', { name: /Details ansehen|Details anzeigen|View details/i })
      .first();

    await expect(standardDetailsButton).toBeVisible();
    await standardDetailsButton.click();

    await expect(page.getByRole('dialog')).toBeVisible();
    await page.getByRole('link', { name: /Jetzt bestellen|Order now/i }).click();

    await expect(page).toHaveURL(/(bestellen|checkout)/);
    await page.getByRole('button', { name: /^Weiter$/ }).first().click();

    await expect(page.locator('input[name="first_name"]')).toBeVisible();

    await page.fill('input[name="first_name"]', 'Playwright');
    await page.fill('input[name="last_name"]', 'Tester');
    await page.fill('input[name="email"]', email);
    const addressInput = page.locator('input[name="address"]');
    if (await addressInput.isVisible()) {
      await addressInput.fill('Teststr. 1, 12345 Berlin');
    }

    const phoneInput = page.locator('input[name="phone"]');
    if (await phoneInput.isVisible()) {
      await phoneInput.fill('+49123456789');
    }

    const usernameInput = page.locator('input[name="username"]');
    if (await usernameInput.isVisible()) {
      await usernameInput.fill(email);
    }
    await page.fill('input[name="password"]', password);
    await page.fill('input[name="password_confirmation"]', password);
    await page.check('input[name="privacy_consent"]');
    await page.getByRole('button', { name: /^Registrieren$/ }).last().click();

    await expect(page.getByPlaceholder(/Gutscheincode/i)).toBeVisible();

    await page.getByPlaceholder(/Gutscheincode/i).fill('PERCENT10');
    await page.getByRole('button', { name: /Gutschein anwenden|Apply coupon/i }).click();
    await expect(
      page.getByText(/Gutschein PERCENT10 aktiviert|Coupon PERCENT10 applied/i)
    ).toBeVisible();

    const termsCheckbox = page.locator('#checkout-terms-hero');
    await expect(termsCheckbox).toBeVisible();
    await termsCheckbox.click();

    await page.getByRole('button', { name: /Weiter mit Paddle|Continue with Paddle/i }).first().click();

    let checkoutMode: 'inline' | 'hosted' | null = null;
    for (let i = 0; i < 8; i++) {
      const state = await page.evaluate(() => ({
        inline: Boolean(window.__paddleCheckoutConfig),
        opened: window.__openedWindows?.length ?? 0,
      }));

      if (state.inline) {
        checkoutMode = 'inline';
        break;
      }

      if (state.opened > 0) {
        checkoutMode = 'hosted';
        break;
      }

      await page.waitForTimeout(300);
    }

    expect(checkoutMode).not.toBeNull();

    if (checkoutMode === 'hosted') {
      await expect.poll(async () => {
        return page.evaluate(() => window.__openedWindows?.[0]?.[0] ?? null);
      }).toContain('https://sandbox.paddle.test/checkout/abc123');
    }

    await page.evaluate(() => {
      window.__paddleEventCallback?.({ name: 'checkout.completed' });
    });

    let session = null;
    for (let i = 0; i < 6; i++) {
      session = await getLatestCheckoutSession({ email });
      if (session) {
        break;
      }
      await page.waitForTimeout(500);
    }

    if (session) {
      await simulatePaddleCompletion(session.id);

      for (let i = 0; i < 6; i++) {
        const refreshed = await getLatestCheckoutSession({ email });
        if (refreshed?.status === 'completed') {
          session = refreshed;
          break;
        }
        await page.waitForTimeout(500);
      }

      expect(session?.status).toBe('completed');
    }

    await expect(page.getByText(/Marketing-Dashboard/)).toBeVisible();
    await expect(
      page.getByRole('button', { name: /Zum Admin-Bereich|To Admin Area/i })
    ).toBeVisible();

    if (paddleRequestPayload) {
      expect(paddleRequestPayload['coupon_code']).toBe('PERCENT10');
    }

    const messages = await getTestMailbox();
    expect(messages.length).toBeGreaterThan(0);
  });
});

declare global {
  interface Window {
    __openedWindows?: unknown[];
    __paddleEventCallback?: ((event: { name: string }) => void) | null;
    __paddleInitOptions?: unknown;
    __paddleCheckoutConfig?: unknown;
  }
}
