// ── Shadow DOM isolation tests ──────────────────────────────────
//
// The #1 historical pain point with the WP plugin is that WordPress themes
// consistently override the payment fields' CSS, making every merchant install
// look different. The new SDK puts the entire UI inside a Shadow DOM via
// `<wcp-payment-fields>`. These tests assert that the encapsulation actually
// holds against hostile theme stylesheets.
//
// Run: `npx playwright test tests/theme-regression/shadow-isolation.spec.ts`
//
// Setup: depends on the web-component bundle being built — run `npm run build`
// in this package first. Tests load `tests/theme-regression/fixture.html` as a
// file:// URL; no WP install is needed.

import { test, expect, type Page } from '@playwright/test';
import { HOSTILE_THEMES } from './themes';

// ESM-safe path resolution (package has `"type": "module"`).
const FIXTURE = new URL('./fixture.html', import.meta.url).href;

interface StyleSnapshot {
  fontFamily: string;
  fontSize: string;
  color: string;
  background: string;
  borderRadius: string;
  width: number;
  height: number;
}

async function snapshotTrustText(page: Page): Promise<StyleSnapshot> {
  return page.evaluate(() => {
    const el = document.querySelector('wcp-payment-fields');
    if (!el?.shadowRoot) throw new Error('shadow root not present');
    const trustText = el.shadowRoot.querySelector('.wcp-pf__trust-text');
    if (!trustText) throw new Error('.wcp-pf__trust-text missing');
    const cs = getComputedStyle(trustText);
    const rect = trustText.getBoundingClientRect();
    return {
      fontFamily: cs.fontFamily,
      fontSize: cs.fontSize,
      color: cs.color,
      background: cs.backgroundColor,
      borderRadius: cs.borderRadius,
      width: rect.width,
      height: rect.height,
    };
  });
}

async function snapshotFirstField(page: Page): Promise<StyleSnapshot> {
  return page.evaluate(() => {
    const el = document.querySelector('wcp-payment-fields');
    if (!el?.shadowRoot) throw new Error('shadow root not present');
    const field = el.shadowRoot.querySelector('.wcp-pf__field');
    if (!field) throw new Error('.wcp-pf__field missing');
    const cs = getComputedStyle(field);
    const rect = field.getBoundingClientRect();
    return {
      fontFamily: cs.fontFamily,
      fontSize: cs.fontSize,
      color: cs.color,
      background: cs.backgroundColor,
      borderRadius: cs.borderRadius,
      width: rect.width,
      height: rect.height,
    };
  });
}

test.describe('Shadow DOM isolation', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto(FIXTURE);
    // Give the SDK a moment to register + render (Clover loader fails, but the
    // UI shell renders regardless of Clover SDK load status — that's what we test).
    await page.waitForSelector('wcp-payment-fields');
    await page.waitForFunction(() => {
      const el = document.querySelector('wcp-payment-fields');
      return Boolean(el?.shadowRoot && el.shadowRoot.querySelector('.wcp-pf'));
    });
  });

  test('shadowRoot mounts and renders the widget chrome', async ({ page }) => {
    const snapshot = await snapshotTrustText(page);
    expect(snapshot.fontSize).toBeTruthy();
    expect(snapshot.width).toBeGreaterThan(0);
  });

  for (const theme of HOSTILE_THEMES) {
    test(`hostile theme "${theme.name}" does not alter shadowRoot styles`, async ({ page }) => {
      const baselineTrust = await snapshotTrustText(page);
      const baselineField = await snapshotFirstField(page);

      // Inject the hostile theme CSS into the document.
      await page.evaluate((css) => {
        const mount = document.getElementById('hostile-theme-mount');
        if (mount) mount.textContent = css;
      }, theme.css);

      // Wait a tick for any potential restyle.
      await page.waitForTimeout(100);

      const afterTrust = await snapshotTrustText(page);
      const afterField = await snapshotFirstField(page);

      // All shadow-internal styles must remain unchanged.
      expect(afterTrust).toEqual(baselineTrust);
      expect(afterField).toEqual(baselineField);
    });
  }

  test('field positions remain stable across all hostile themes applied in sequence', async ({ page }) => {
    const baseline = await snapshotFirstField(page);
    for (const theme of HOSTILE_THEMES) {
      await page.evaluate((css) => {
        const mount = document.getElementById('hostile-theme-mount');
        if (mount) mount.textContent = css;
      }, theme.css);
      await page.waitForTimeout(50);
      const snapshot = await snapshotFirstField(page);
      expect(snapshot, `theme "${theme.name}" altered field`).toEqual(baseline);
    }
  });
});
