import { test, expect } from '@playwright/test';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { adminPath, apiList, apiPost, ensureDataSource, ensureMailshot, cleanupByNames } from './helpers.mjs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const renewalsTemplate = fs.readFileSync(path.resolve(__dirname, '../../../formats/renewals_v4.html'), 'utf8');

const dsName = process.env.E2E_RENEWAL_DATASOURCE || 'renewal_accounts_with_contacts';
const mailshotPurpose = process.env.E2E_RENEWAL_MAILSHOT_PURPOSE || 'Renewals (pending accounts and contacts)';
const allowCreate = process.env.E2E_RENEWAL_ALLOW_CREATE === '1';
const runEnabled = process.env.E2E_RENEWAL_ENABLE === '1';

test.describe('renewal dataset: download pdf e2e', () => {
  test.skip(!runEnabled, 'Enable with E2E_RENEWAL_ENABLE=1');

  const clickAndExpectDownload = async (page, buttonName, expectedFilenamePart) => {
    page.once('dialog', async (dialog) => {
      await dialog.accept();
    });

    const nextMatchingDownload = async () => {
      const deadline = Date.now() + 240000;
      while (Date.now() < deadline) {
        const remaining = Math.max(1, deadline - Date.now());
        const download = await page.waitForEvent('download', { timeout: remaining }).catch(() => null);
        if (!download) {
          break;
        }
        if (download.suggestedFilename().includes(expectedFilenamePart)) {
          return download;
        }
      }
      return null;
    };

    const downloadPromise = nextMatchingDownload();
    await page.getByRole('button', { name: buttonName }).click();

    let downloaded;
    try {
      downloaded = await downloadPromise;
    } catch {
      const critical = page.getByText('There has been a critical error on this website.');
      if (await critical.count()) {
        throw new Error(`Download action "${buttonName}" reached a WordPress critical error page.`);
      }
      const failBanner = page.locator('strong', { hasText: 'PDF generation failed.' });
      if (await failBanner.count()) {
        const msg = (await page.locator('.wrap').innerText()).replace(/\s+/g, ' ').trim();
        throw new Error(`Download action "${buttonName}" failed in UI: ${msg}`);
      }
      throw new Error(`Download action "${buttonName}" timed out waiting for file download.`);
    }
    if (!downloaded) {
      throw new Error(`Download action "${buttonName}" did not produce expected file "${expectedFilenamePart}".`);
    }

    expect(downloaded.suggestedFilename()).toContain(expectedFilenamePart);
    const outPath = await downloaded.path();
    expect(outPath).toBeTruthy();
    const outSize = fs.statSync(outPath).size;
    expect(outSize).toBeGreaterThan(1000);
  };

  const resolveMailshot = async (request) => {
    const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
    const purpose = `e2e_renewal_download_${uniq}`;
    const dsCreatedName = `e2e_renewal_ds_${uniq}`;

    let mailshotId = '';
    let effectiveDsName = dsName;
    let createdMailshot = false;
    const mailshotList = await apiList(request, 'feca_mailshots_mailshots_api');
    expect(mailshotList.ok).toBeTruthy();
    const existing = (mailshotList.items || []).find(
      (row) => String(row.Purpose || '') === mailshotPurpose
    );

    if (existing) {
      mailshotId = String(existing.id || '');
      effectiveDsName = String(existing.DataSource || '').trim();
      if (effectiveDsName === '') {
        throw new Error(`Mailshot "${mailshotPurpose}" has no DataSource.`);
      }
    } else {
      const dsList = await apiList(request, 'feca_mailshots_data_sources_api');
      expect(dsList.ok).toBeTruthy();
      const dsExists = (dsList.items || []).some((row) => String(row.name || '') === dsName);
      if (!dsExists) {
        if (!allowCreate) {
          throw new Error(`Required data source not found: ${dsName}`);
        }
        await ensureDataSource(request, dsCreatedName, dsName);
        effectiveDsName = dsCreatedName;
      }
      if (!allowCreate) {
        throw new Error(`Required mailshot not found: ${mailshotPurpose}`);
      }
      const saved = await ensureMailshot(request, {
        Purpose: purpose,
        DataSource: effectiveDsName,
        CC: '',
        BCC: '',
        Subject: 'Renewal for {{ account_name }}',
        Message: '',
        PDFAttachment: renewalsTemplate,
        AttachmentNames: '[]',
        PDFFilenameDerivedFrom: 'account_name',
        RecipientEmailField: '',
        ReplyTo: ''
      });
      mailshotId = String(saved.id || '');
      createdMailshot = true;
    }
    expect(mailshotId).not.toBe('');

    const dsListFinal = await apiList(request, 'feca_mailshots_data_sources_api');
    expect(dsListFinal.ok).toBeTruthy();
    const effectiveDsExists = (dsListFinal.items || []).some((row) => String(row.name || '') === effectiveDsName);
    expect(effectiveDsExists).toBeTruthy();

    const render = await apiPost(request, 'feca_mailshots_test_api', 'render_test', {
      mailshot_id: mailshotId,
      recipient_index: '0'
    });
    expect(render.ok).toBeTruthy();
    expect(String(render?.rendered?.pdf_attachment || '')).toContain('Membership Renewal');

    return {
      mailshotId,
      cleanup: async () => {
        await cleanupByNames(request, {
          dataSourceNames: [dsCreatedName],
          mailshotPurposes: createdMailshot ? [purpose] : []
        });
      }
    };
  };

  test('downloads merged PDF for renewal_accounts_with_contacts', async ({ page, request }) => {
    const resolved = await resolveMailshot(request);
    try {
      await page.goto(`${adminPath('feca-mailshots-download-pdf')}&mailshot_id=${encodeURIComponent(resolved.mailshotId)}`);
      await expect(page.getByRole('heading', { name: 'Download PDF' })).toBeVisible();
      await page.locator('#dp_mailshot_id').selectOption(resolved.mailshotId);

      await clickAndExpectDownload(page, 'Download Merged PDF', '_merged.pdf');
    } finally {
      try {
        await resolved.cleanup();
      } catch {
        // best effort cleanup
      }
    }
  });

  test('downloads ZIP of PDFs for renewal_accounts_with_contacts', async ({ page, request }) => {
    const resolved = await resolveMailshot(request);
    try {
      await page.goto(`${adminPath('feca-mailshots-download-pdf')}&mailshot_id=${encodeURIComponent(resolved.mailshotId)}`);
      await expect(page.getByRole('heading', { name: 'Download PDF' })).toBeVisible();
      await page.locator('#dp_mailshot_id').selectOption(resolved.mailshotId);
      await clickAndExpectDownload(page, 'Download ZIP of PDFs', '_pdfs.zip');
    } finally {
      try {
        await resolved.cleanup();
      } catch {
        // best effort cleanup
      }
    }
  });
});
