import { test, expect } from '@playwright/test';
import { execSync } from 'child_process';

const LOGIN_EMAIL = 'checkout-e2e@example.com';
const LOGIN_PASSWORD = 'Password123!';

test.describe('Checkout Payment Step – Paddle flow', () => {
  test.beforeAll(async () => {
    execSync(
      `php artisan tenant:add-dummy --email=${LOGIN_EMAIL} --password=${LOGIN_PASSWORD} --first_name=Checkout --last_name=Tester --address="Playwrightstr. 1" --phone="+4912345678"`
    );

    execSync(
      `php artisan tinker --execute="App\\\\Models\\\\User::where('email', '${LOGIN_EMAIL}')->update(['email_verified_at' => now()]);"`
    );
  });

  test.beforeEach(async ({ page }) => {
    await page.goto('/login');
    await page.fill('input[name="email"]', LOGIN_EMAIL);
    await page.fill('input[name="password"]', LOGIN_PASSWORD);
    await page.getByRole('button', { name: /Anmelden|Login/ }).click();
    await expect(page).toHaveURL(/dashboard/);
  });

  test('opens Paddle checkout and shows success notice', async ({ page }) => {
    await page.route('**/paddle/create-checkout', async (route) => {
      const request = route.request();
      const postData = request.postDataJSON() as { inline?: boolean } | null;
      const inline = Boolean(postData?.inline);

      if (inline) {
        await route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            mode: 'inline',
            items: [
              { priceId: 'pri_123', quantity: 1 },
            ],
            custom_data: {
              tenant_id: '1',
              package_id: '2',
              checkout_session_id: 'cs_123',
            },
            customer: {
              email: LOGIN_EMAIL,
            },
          }),
        });
        return;
      }

      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);

    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/ }).click();

    await expect(
      page.locator(
        'text=/Paddle checkout is running in a secure overlay|Der Paddle-Checkout läuft jetzt in einem Overlay/'
      )
    ).toBeVisible();

    await expect.poll(async () => {
      return page.evaluate(() => window.__paddleOpenConfig?.items?.[0]?.priceId ?? null);
    }).toBe('pri_123');

    await expect.poll(async () => {
      return page.evaluate(() => window.__openedUrls?.length ?? 0);
    }).toBe(0);
  });

  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 openCheckoutPaymentStep(page);

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

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

async function openCheckoutPaymentStep(page: import('@playwright/test').Page) {
    await page.goto('/packages');
    const checkoutLink = page.locator('a[href^="/checkout/"]').first();
    const href = await checkoutLink.getAttribute('href');

    if (!href) {
      throw new Error('No checkout link found on packages page.');
    }

    await page.goto(href);

    const nextButton = page.getByRole('button', {
      name: /Weiter zum Zahlungsschritt|Continue to Payment/,
    });
    if (await nextButton.isVisible()) {
      await nextButton.click();
    }

    await page.waitForSelector('text=/Zahlung|Payment/');
}

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>;
  }
}
