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

const demoTenantCredentials = {
  email: process.env.E2E_DEMO_TENANT_EMAIL ?? 'tenant-demo@fotospiel.app',
  password: process.env.E2E_DEMO_TENANT_PASSWORD ?? 'Demo1234!',
};

test.describe('Checkout Payment Step – Paddle flow', () => {
  test('opens Paddle checkout and shows success notice', async ({ page }) => {
    await page.route('**/paddle/create-checkout', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          checkout_url: 'https://paddle.test/checkout/success',
        }),
      });
    });

    await page.route('https://cdn.paddle.com/paddle/v2/paddle.js', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/javascript',
        body: `
          window.Paddle = {
            Environment: { set: function(env) { window.__paddleEnv = env; } },
            Initialize: function(opts) { window.__paddleInit = opts; },
            Checkout: {
              open: function(config) {
                window.__paddleOpenConfig = config;
              }
            }
          };
        `,
      });
    });

    await openCheckoutPaymentStep(page, demoTenantCredentials);
    await acceptCheckoutTerms(page);

    await page.evaluate(() => {
      window.__openedUrls = [];
      window.open = (url: string, target?: string | null, features?: string | null) => {
        window.__openedUrls.push({ url, target: target ?? null, features: features ?? null });
        return null;
      };
    });

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

    await expect(
      page.locator(
        'text=/secure overlay|Overlay|neuen Tab|new tab/i'
      )
    ).toBeVisible();

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

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

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

      await page.waitForTimeout(300);
    }

    expect(mode).not.toBeNull();

    if (mode === 'inline') {
      const inlineConfig = await page.evaluate(() => window.__paddleOpenConfig ?? null);
      expect(inlineConfig).not.toBeNull();
    }

    if (mode === 'hosted') {
      await expect.poll(async () => {
        return page.evaluate(() => window.__openedUrls?.[0]?.url ?? null);
      }).toContain('paddle');
    }
  });

  test('shows error state when Paddle checkout creation fails', async ({ page }) => {
    await page.route('**/paddle/create-checkout', async (route) => {
      await route.fulfill({
        status: 500,
        contentType: 'application/json',
        body: JSON.stringify({ message: 'test-error' }),
      });
    });

    await page.route('https://cdn.paddle.com/paddle/v2/paddle.js', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/javascript',
        body: `
          window.Paddle = {
            Environment: { set: function(env) { window.__paddleEnv = env; } },
            Initialize: function(opts) { window.__paddleInit = opts; },
            Checkout: {
              open: function() {
                throw new Error('forced paddle failure');
              }
            }
          };
        `,
      });
    });

    await openCheckoutPaymentStep(page, demoTenantCredentials);
    await acceptCheckoutTerms(page);

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

    await expect(
      page.locator('text=/Paddle-Checkout konnte nicht gestartet werden|Paddle checkout could not be started/i')
    ).toBeVisible();
  });
});

async function openCheckoutPaymentStep(
  page: import('@playwright/test').Page,
  credentials: { email: string; password: string }
) {
  await page.goto('/packages');

  const detailsButtons = page.getByRole('button', {
    name: /Details ansehen|Details anzeigen|View details/i,
  });
  await expect(detailsButtons.first()).toBeVisible();
  await detailsButtons.first().click();

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

  await expect(page).toHaveURL(/\/(bestellen|checkout)\/\d+/);

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

  const continueButton = page.getByRole('button', { name: /Weiter zur Zahlung|Continue to Payment/i });
  if (await continueButton.isVisible()) {
    await continueButton.click();
  } else {
    await page.getByRole('button', { name: /^Anmelden$/ }).first().click();
    await expect(page.locator('input[name="identifier"]')).toBeVisible();
    await page.fill('input[name="identifier"]', credentials.email);
    await page.fill('input[name="password"]', credentials.password);
    await page.getByRole('button', { name: /^Anmelden$/ }).last().click();
  }

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

async function acceptCheckoutTerms(page: import('@playwright/test').Page) {
  const termsCheckbox = page.locator('#checkout-terms-hero');
  await expect(termsCheckbox).toBeVisible();
  await termsCheckbox.click();
}

declare global {
  interface Window {
    __openedUrls?: Array<{ url: string; target?: string | null; features?: string | null }>;
    __paddleOpenConfig?: { url?: string; items?: Array<{ priceId: string; quantity: number }>; settings?: { displayMode?: string } };
    __paddleEnv?: string;
    __paddleInit?: Record<string, unknown>;
  }
}
