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

/**
 * E2E Tests for Bulk Receipt Upload (US-005)
 *
 * Prerequisites:
 *   1. Start the test environment: ./start-test.sh
 *   2. Ensure backend is running on port 8000
 *   3. Ensure frontend is running on port 3000
 *
 * Run:
 *   npm run test:e2e
 *   npm run test:e2e:headed  # With visible browser
 *
 * Test PDFs are located in: docs/data-entry/
 */

// Test configuration
const TEST_USER = {
  username: 'MARIUS M',
  password: '123',
  company: 'MARIUSM AUTO'
};

// Sample test PDFs from docs/data-entry/
const TEST_PDFS = [
  'benzina 13 iulie.pdf',
  'brick igiena 604.pdf',
  'electrobering igiena iulie 604.pdf'
];

// Corrupted file for error handling test
const CORRUPTED_FILE = 'test-corrupted.txt';

test.describe('Bulk Receipt Upload E2E Tests', () => {

  test.beforeEach(async ({ page }) => {
    // Navigate to login page
    await page.goto('/');

    // Wait for login page to load
    await page.waitForSelector('input[placeholder*="Utilizator"]', { timeout: 10000 });

    // Fill login credentials
    await page.fill('input[placeholder*="Utilizator"]', TEST_USER.username);
    await page.fill('input[type="password"]', TEST_USER.password);

    // Click login button
    await page.click('button:has-text("Autentificare")');

    // Wait for redirect after login
    await page.waitForURL(/\/(reports|data-entry)/, { timeout: 15000 });

    // Select company if modal appears
    const companyModal = page.locator('.company-select-modal');
    if (await companyModal.isVisible({ timeout: 2000 }).catch(() => false)) {
      await page.click(`text="${TEST_USER.company}"`);
    }
  });

  test('should navigate to bulk upload page', async ({ page }) => {
    // Navigate to data entry module
    await page.goto('/data-entry/bulk-upload');

    // Verify page title
    await expect(page.locator('h1')).toContainText('Upload Bonuri în Lot');

    // Verify upload zone is visible
    await expect(page.locator('.bulk-upload-zone')).toBeVisible();
  });

  test('should upload 3 real PDF receipts and process them', async ({ page }) => {
    // Navigate to bulk upload page
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    // Get file paths
    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = TEST_PDFS.map(f => path.join(testFilesPath, f));

    // Upload files via file input
    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    // Verify files appear in the list
    await expect(page.locator('.bulk-file-list')).toBeVisible();
    await expect(page.locator('.file-item')).toHaveCount(3);

    // Verify file names are shown
    for (const pdfName of TEST_PDFS) {
      await expect(page.locator(`.file-item:has-text("${pdfName}")`)).toBeVisible();
    }

    // Verify total count message
    await expect(page.locator('text=/3 fișier/')).toBeVisible();

    // Click process button
    await page.click('button:has-text("Procesează")');

    // Wait for upload to complete and processing to start
    await expect(page.locator('.bulk-progress-bar')).toBeVisible({ timeout: 10000 });

    // Wait for all files to be processed (up to 3 minutes for OCR)
    await page.waitForFunction(() => {
      const progress = document.querySelector('.bulk-progress-bar');
      if (!progress) return false;
      const text = progress.textContent || '';
      // Check if all 3 are processed (3/3)
      return text.includes('3/3') || text.includes('100%');
    }, { timeout: 180000 });

    // Verify summary modal appears
    await expect(page.locator('.bulk-summary-modal, .p-dialog')).toBeVisible({ timeout: 10000 });

    // Verify success count
    await expect(page.locator('.success-count, .stat-success .stat-value')).toBeVisible();

    // Get the number of successful receipts
    const successCount = await page.locator('.success-count, .stat-success .stat-value').textContent();
    console.log(`Successfully processed: ${successCount} receipts`);

    // Verify total amount is displayed
    await expect(page.locator('.total-amount')).toBeVisible();
  });

  test('should show receipts in list after processing', async ({ page }) => {
    // First upload and process files (abbreviated version)
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = TEST_PDFS.slice(0, 1).map(f => path.join(testFilesPath, f));

    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    await page.click('button:has-text("Procesează")');

    // Wait for processing to complete
    await page.waitForFunction(() => {
      const modal = document.querySelector('.bulk-summary-modal, .p-dialog');
      return modal && window.getComputedStyle(modal).display !== 'none';
    }, { timeout: 120000 });

    // Click "Vezi bonurile create" link
    await page.click('button:has-text("Vezi bonurile create")');

    // Verify navigation to receipts list
    await expect(page).toHaveURL(/\/data-entry/);

    // Verify receipts are listed
    await expect(page.locator('.receipts-table, .p-datatable')).toBeVisible({ timeout: 10000 });
  });

  test('should handle file removal before upload', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = TEST_PDFS.map(f => path.join(testFilesPath, f));

    // Upload files
    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    // Verify 3 files are listed
    await expect(page.locator('.file-item')).toHaveCount(3);

    // Click remove button on first file
    await page.locator('.file-item').first().locator('button.btn-remove, .pi-times').click();

    // Verify only 2 files remain
    await expect(page.locator('.file-item')).toHaveCount(2);
  });

  test('should clear all files with "Golește lista" button', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = TEST_PDFS.map(f => path.join(testFilesPath, f));

    // Upload files
    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    // Verify files are listed
    await expect(page.locator('.file-item')).toHaveCount(3);

    // Click clear button
    await page.click('button:has-text("Golește lista")');

    // Verify list is empty
    await expect(page.locator('.file-item')).toHaveCount(0);
    await expect(page.locator('.bulk-file-list')).not.toBeVisible();
  });

  test('should show progress during processing', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = TEST_PDFS.slice(0, 2).map(f => path.join(testFilesPath, f));

    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    await page.click('button:has-text("Procesează")');

    // Verify progress bar appears
    await expect(page.locator('.bulk-progress-bar')).toBeVisible({ timeout: 10000 });

    // Verify progress list shows items
    await expect(page.locator('.bulk-progress-list')).toBeVisible();

    // Verify status badges are shown
    await expect(page.locator('.status-badge, .p-tag')).toBeVisible();
  });

  test('should disable upload zone during processing', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = [path.join(testFilesPath, TEST_PDFS[0])];

    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    await page.click('button:has-text("Procesează")');

    // Wait for processing to start
    await expect(page.locator('.bulk-progress-bar')).toBeVisible({ timeout: 10000 });

    // Verify upload zone is disabled
    const uploadZone = page.locator('.bulk-upload-zone');
    await expect(uploadZone).toHaveClass(/disabled/);

    // Verify process button is disabled
    await expect(page.locator('button:has-text("Procesează")')).toBeDisabled();
  });

  test('should allow loading new batch after completion', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = [path.join(testFilesPath, TEST_PDFS[0])];

    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    await page.click('button:has-text("Procesează")');

    // Wait for summary modal
    await page.waitForFunction(() => {
      const modal = document.querySelector('.bulk-summary-modal, .p-dialog');
      return modal && window.getComputedStyle(modal).display !== 'none';
    }, { timeout: 120000 });

    // Click "Încarcă alt batch" button
    await page.click('button:has-text("Încarcă alt batch")');

    // Verify modal closes and upload zone is enabled
    await expect(page.locator('.bulk-summary-modal, .p-dialog')).not.toBeVisible();
    await expect(page.locator('.bulk-upload-zone')).toBeVisible();
    await expect(page.locator('.bulk-upload-zone')).not.toHaveClass(/disabled/);
  });

});

test.describe('Bulk Upload Error Handling', () => {

  test.beforeEach(async ({ page }) => {
    await page.goto('/');
    await page.waitForSelector('input[placeholder*="Utilizator"]', { timeout: 10000 });
    await page.fill('input[placeholder*="Utilizator"]', TEST_USER.username);
    await page.fill('input[type="password"]', TEST_USER.password);
    await page.click('button:has-text("Autentificare")');
    await page.waitForURL(/\/(reports|data-entry)/, { timeout: 15000 });
  });

  test('should reject files with invalid MIME type', async ({ page }) => {
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    // Create a text file (invalid type)
    const fileInput = page.locator('input[type="file"]');

    // Try to set a text file - should be rejected by client-side validation
    // Note: This tests the accept attribute on the file input
    const acceptAttr = await fileInput.getAttribute('accept');
    expect(acceptAttr).toContain('pdf');
    expect(acceptAttr).toContain('image');
  });

  test('should show error message when upload fails', async ({ page }) => {
    // Navigate to bulk upload with backend not running on a specific endpoint
    await page.goto('/data-entry/bulk-upload');
    await page.waitForSelector('.bulk-upload-zone', { timeout: 10000 });

    const testFilesPath = path.join(process.cwd(), 'docs', 'data-entry');
    const filePaths = [path.join(testFilesPath, TEST_PDFS[0])];

    const fileInput = page.locator('input[type="file"]');
    await fileInput.setInputFiles(filePaths);

    // Intercept the upload request and make it fail
    await page.route('**/api/data-entry/bulk/upload', route => {
      route.fulfill({
        status: 500,
        body: JSON.stringify({ detail: 'Internal server error' })
      });
    });

    await page.click('button:has-text("Procesează")');

    // Verify error message appears
    await expect(page.locator('.error-message')).toBeVisible({ timeout: 10000 });
    await expect(page.locator('.error-message')).toContainText(/eroare|error/i);
  });

});
