import { test, expect } from '@playwright/test';
import { adminPath, apiPost, cleanupByNames, ensureDataSource } from './helpers.mjs';

test('data sources: create + preview + validation failure path', async ({ page, request }) => {
  const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
  const dsName = `e2e_ds_${uniq}`;

  try {
    await page.goto(adminPath('feca-mailshot-data-sources'));
    await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();

    await page.getByRole('button', { name: 'New Data Source' }).click();
    await page.locator('#ds_name').fill(dsName);
    await page.locator('#ds_dsl').fill('contacts and accounts');
    await page.getByRole('button', { name: /^Create|Save$/ }).first().click();

    await expect(page.getByRole('cell', { name: dsName })).toBeVisible();

    const preview = await apiPost(request, 'feca_mailshots_data_sources_api', 'preview', {
      dsl_text: 'contacts and accounts',
      limit: '10'
    });
    expect(preview._httpStatus).toBe(200);
    expect(JSON.stringify(preview)).not.toContain('Duplicate column name');

    const invalid = await apiPost(request, 'feca_mailshots_data_sources_api', 'validate', {
      dsl_text: 'unknownsource'
    });
    expect(invalid._httpStatus).toBe(200);
    expect(Array.isArray(invalid.errors)).toBeTruthy();
    expect(invalid.errors.join(' | ')).toContain('Unknown source');
  } finally {
    try {
      await cleanupByNames(request, { dataSourceNames: [dsName] });
    } catch {
      // best effort
    }
  }
});

test('data sources: duplicate row action creates editable copy', async ({ page, request }) => {
  const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
  const dsName = `e2e_ds_duplicate_${uniq}`;
  const copyName = `Copy of ${dsName}`;

  try {
    await ensureDataSource(request, dsName, 'contacts and accounts');

    await page.goto(adminPath('feca-mailshot-data-sources'));
    await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();

    const row = page.locator('tr', {
      has: page.getByRole('cell', { name: dsName })
    }).first();
    await expect(row).toBeVisible();
    await row.getByRole('button', { name: 'Duplicate' }).click();

    const copyRow = page.locator('tr', {
      has: page.getByRole('cell', { name: copyName })
    }).first();
    await expect(copyRow).toBeVisible();
    await copyRow.getByRole('link', { name: 'Edit' }).click();

    await expect(page.locator('#ds-editor-modal')).toBeVisible();
    await expect(page.locator('#ds_name')).toHaveValue(copyName);
    await expect(page.locator('#ds_dsl')).toHaveValue('contacts and accounts');
  } finally {
    try {
      await cleanupByNames(request, { dataSourceNames: [dsName, copyName] });
    } catch {
      // best effort
    }
  }
});

test('data sources: DSL builder round-trip preserves complex representable DSL', async ({ page, request }) => {
  const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
  const dsName = `e2e_ds_roundtrip_${uniq}`;
  const dsl =
    "contacts and accounts where fen1-contact and not (primary-contact) and contacts.account_id = accounts.id and contacts.last_name contains 'smith' and accounts.id in (123) and accounts.name starts-with 'St' and accounts.name ends-with 'Ltd' and contacts.phone_1 blank and contacts.account_id != accounts.id";

  try {
    await ensureDataSource(request, dsName, dsl);

    await page.goto(adminPath('feca-mailshot-data-sources'));
    await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();

    const row = page.locator('tr', {
      has: page.getByRole('cell', { name: dsName })
    }).first();
    await expect(row).toBeVisible();
    await row.getByRole('link', { name: 'Edit' }).click();

    await expect(page.locator('#ds-editor-modal')).toBeVisible();
    await expect(page.locator('#ds_dsl')).toHaveValue(dsl);

    await page.locator('#ds-build-dsl-open').click();
    await expect(page.locator('#ds-builder-modal')).toBeVisible();
    await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);

    await page.locator('#ds-builder-apply').click();
    await expect(page.locator('#ds_dsl')).toHaveValue(dsl);

    await page.locator('#ds-build-dsl-open').click();
    await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);
  } finally {
    try {
      await cleanupByNames(request, { dataSourceNames: [dsName] });
    } catch {
      // best effort
    }
  }
});

test('data sources: DSL builder round-trip preserves FEN built-in filters', async ({ page, request }) => {
  const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
  const dsName = `e2e_ds_fen_roundtrip_${uniq}`;
  const dsl =
    'invoices and ads and advertisers where invoice-ids(10, 11) and issue(202605) and selected';

  try {
    await ensureDataSource(request, dsName, dsl);

    await page.goto(adminPath('feca-mailshot-data-sources'));
    await expect(page.getByRole('heading', { name: 'Mailshot Data Sources' })).toBeVisible();

    const row = page.locator('tr', {
      has: page.getByRole('cell', { name: dsName })
    }).first();
    await expect(row).toBeVisible();
    await row.getByRole('link', { name: 'Edit' }).click();

    await expect(page.locator('#ds-editor-modal')).toBeVisible();
    await expect(page.locator('#ds_dsl')).toHaveValue(dsl);

    await page.locator('#ds-build-dsl-open').click();
    await expect(page.locator('#ds-builder-modal')).toBeVisible();
    await expect(page.locator('#ds-builder-output')).toHaveValue(dsl);

    await page.locator('#ds-builder-apply').click();
    await expect(page.locator('#ds_dsl')).toHaveValue(dsl);
  } finally {
    try {
      await cleanupByNames(request, { dataSourceNames: [dsName] });
    } catch {
      // best effort
    }
  }
});
