import { test, expect } from '@playwright/test';
import { drawSelectionRectangle } from '../helpers/selection.js';
import { navigateToDate, closeOnboardingModal } from '../helpers/navigation.js';
import { waitForMap, enableLayer } from '../helpers/map.js';

test.describe('Bulk Delete Points @destructive', () => {
  test.beforeEach(async ({ page }) => {
    // Navigate to map page
    await page.goto('/map', {
      waitUntil: 'domcontentloaded',
      timeout: 30000
    });

    // Wait for map to be initialized
    await waitForMap(page);

    // Close onboarding modal if present
    await closeOnboardingModal(page);

    // Navigate to a date with points (October 15, 2024)
    await navigateToDate(page, '2024-10-15T00:00', '2024-10-15T23:59');

    // Enable Points layer
    await enableLayer(page, 'Points');
  });

  test('should show area selection tool button', async ({ page }) => {
    // Check that area selection button exists
    const selectionButton = page.locator('#selection-tool-button');
    await expect(selectionButton).toBeVisible();
  });

  test('should enable selection mode when area tool is clicked', async ({ page }) => {
    // Click area selection button
    const selectionButton = page.locator('#selection-tool-button');
    await selectionButton.click();
    await page.waitForTimeout(500);

    // Verify selection mode is active
    const isSelectionActive = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.visitsManager?.selectionMode === true;
    });

    expect(isSelectionActive).toBe(true);
  });

  test('should select points in drawn area and show delete button', async ({ page }) => {
    await drawSelectionRectangle(page);

    // Check that delete button appears
    const deleteButton = page.locator('#delete-selection-button');
    await expect(deleteButton).toBeVisible({ timeout: 10000 });

    // Check button has text "Delete Points"
    await expect(deleteButton).toContainText('Delete Points');
  });

  test('should show point count badge on delete button', async ({ page }) => {
    await drawSelectionRectangle(page);
    await page.waitForTimeout(1000);

    // Check for badge with count
    const badge = page.locator('#delete-selection-button .badge');
    await expect(badge).toBeVisible();

    // Badge should contain a number
    const badgeText = await badge.textContent();
    expect(parseInt(badgeText)).toBeGreaterThan(0);
  });

  test('should show cancel button alongside delete button', async ({ page }) => {
    await drawSelectionRectangle(page);
    await page.waitForTimeout(1000);

    // Check both buttons exist
    const cancelButton = page.locator('#cancel-selection-button');
    const deleteButton = page.locator('#delete-selection-button');

    await expect(cancelButton).toBeVisible();
    await expect(deleteButton).toBeVisible();
    await expect(cancelButton).toContainText('Cancel');
  });

  test('should cancel selection when cancel button is clicked', async ({ page }) => {
    await drawSelectionRectangle(page);
    await page.waitForTimeout(1000);

    // Click cancel button
    const cancelButton = page.locator('#cancel-selection-button');
    await cancelButton.click();
    await page.waitForTimeout(500);

    // Verify buttons are gone
    await expect(cancelButton).not.toBeVisible();
    await expect(page.locator('#delete-selection-button')).not.toBeVisible();

    // Verify selection is cleared
    const isSelectionActive = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.visitsManager?.isSelectionActive === false;
    });

    expect(isSelectionActive).toBe(true);
  });

  test('should show confirmation dialog when delete button is clicked', async ({ page }) => {
    // Set up dialog handler
    let dialogMessage = '';
    page.on('dialog', async dialog => {
      dialogMessage = dialog.message();
      await dialog.dismiss(); // Dismiss to prevent actual deletion
    });

    await drawSelectionRectangle(page);
    await page.waitForTimeout(1000);

    // Click delete button
    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(500);

    // Verify confirmation dialog appeared with warning
    expect(dialogMessage).toContain('WARNING');
    expect(dialogMessage).toContain('permanently delete');
    expect(dialogMessage).toContain('cannot be undone');
  });

  test('should delete points and show success message when confirmed', async ({ page }) => {
    // Set up dialog handler to accept deletion
    page.on('dialog', async dialog => {
      await dialog.accept();
    });

    // Get initial point count
    const initialPointCount = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.markers?.length || 0;
    });

    await drawSelectionRectangle(page);
    await page.waitForTimeout(1000);

    // Click delete button
    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(2000); // Wait for deletion to complete

    // Check for success flash message with specific text
    const flashMessage = page.locator('#flash-messages [role="alert"]:has-text("Successfully deleted")');
    await expect(flashMessage).toBeVisible({ timeout: 5000 });

    const messageText = await flashMessage.textContent();
    expect(messageText).toMatch(/Successfully deleted \d+ point/);

    // Verify point count decreased
    const finalPointCount = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.markers?.length || 0;
    });

    expect(finalPointCount).toBeLessThan(initialPointCount);
  });

  test('should preserve Routes layer disabled state after deletion', async ({ page }) => {
    // Ensure Routes layer is disabled
    await page.locator('.leaflet-control-layers').hover();
    await page.waitForTimeout(300);

    const routesCheckbox = page.locator('.leaflet-control-layers-overlays label:has-text("Routes") input[type="checkbox"]');
    const isRoutesChecked = await routesCheckbox.isChecked();
    if (isRoutesChecked) {
      await routesCheckbox.uncheck();
      await page.waitForTimeout(500);
    }

    // Set up dialog handler to accept deletion
    page.on('dialog', async dialog => {
      await dialog.accept();
    });

    // Perform deletion using same selection logic as helper
    const selectionButton = page.locator('#selection-tool-button');
    await selectionButton.click();
    await page.waitForTimeout(500);

    const mapContainer = page.locator('#map [data-maps-target="container"]');
    const bbox = await mapContainer.boundingBox();

    // Use larger selection area to ensure we select points
    const startX = bbox.x + bbox.width * 0.2;
    const startY = bbox.y + bbox.height * 0.2;
    const endX = bbox.x + bbox.width * 0.8;
    const endY = bbox.y + bbox.height * 0.8;

    await page.mouse.move(startX, startY);
    await page.mouse.down();
    await page.mouse.move(endX, endY, { steps: 10 });
    await page.mouse.up();
    await page.waitForTimeout(2000);

    // Wait for drawer and button to appear
    await page.waitForSelector('#visits-drawer.open', { timeout: 15000 });
    await page.waitForSelector('#delete-selection-button', { timeout: 15000 });

    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(2000);

    // Verify Routes layer is still disabled
    const isRoutesLayerVisible = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.map?.hasLayer(controller?.polylinesLayer);
    });

    expect(isRoutesLayerVisible).toBe(false);
  });

  test('should preserve Routes layer enabled state after deletion', async ({ page }) => {
    // Enable Routes layer
    await page.locator('.leaflet-control-layers').hover();
    await page.waitForTimeout(300);

    const routesCheckbox = page.locator('.leaflet-control-layers-overlays label:has-text("Routes") input[type="checkbox"]');
    const isRoutesChecked = await routesCheckbox.isChecked();
    if (!isRoutesChecked) {
      await routesCheckbox.check();
      await page.waitForTimeout(1000);
    }

    // Set up dialog handler to accept deletion
    page.on('dialog', async dialog => {
      await dialog.accept();
    });

    // Perform deletion using same selection logic as helper
    const selectionButton = page.locator('#selection-tool-button');
    await selectionButton.click();
    await page.waitForTimeout(500);

    const mapContainer = page.locator('#map [data-maps-target="container"]');
    const bbox = await mapContainer.boundingBox();

    // Use larger selection area to ensure we select points
    const startX = bbox.x + bbox.width * 0.2;
    const startY = bbox.y + bbox.height * 0.2;
    const endX = bbox.x + bbox.width * 0.8;
    const endY = bbox.y + bbox.height * 0.8;

    await page.mouse.move(startX, startY);
    await page.mouse.down();
    await page.mouse.move(endX, endY, { steps: 10 });
    await page.mouse.up();
    await page.waitForTimeout(2000);

    // Wait for drawer and button to appear
    await page.waitForSelector('#visits-drawer.open', { timeout: 15000 });
    await page.waitForSelector('#delete-selection-button', { timeout: 15000 });

    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(2000);

    // Verify Routes layer is still enabled
    const isRoutesLayerVisible = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.map?.hasLayer(controller?.polylinesLayer);
    });

    expect(isRoutesLayerVisible).toBe(true);
  });

  test('should update heatmap after bulk deletion', async ({ page }) => {
    // Enable Heatmap layer
    await page.locator('.leaflet-control-layers').hover();
    await page.waitForTimeout(300);

    const heatmapCheckbox = page.locator('.leaflet-control-layers-overlays label:has-text("Heatmap") input[type="checkbox"]');
    const isHeatmapChecked = await heatmapCheckbox.isChecked();
    if (!isHeatmapChecked) {
      await heatmapCheckbox.check();
      await page.waitForTimeout(1000);
    }

    // Get initial heatmap data count
    const initialHeatmapCount = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.heatmapLayer?._latlngs?.length || 0;
    });

    // Set up dialog handler to accept deletion
    page.on('dialog', async dialog => {
      await dialog.accept();
    });

    // Perform deletion using same selection logic as helper
    const selectionButton = page.locator('#selection-tool-button');
    await selectionButton.click();
    await page.waitForTimeout(500);

    const mapContainer = page.locator('#map [data-maps-target="container"]');
    const bbox = await mapContainer.boundingBox();

    // Use larger selection area to ensure we select points
    const startX = bbox.x + bbox.width * 0.2;
    const startY = bbox.y + bbox.height * 0.2;
    const endX = bbox.x + bbox.width * 0.8;
    const endY = bbox.y + bbox.height * 0.8;

    await page.mouse.move(startX, startY);
    await page.mouse.down();
    await page.mouse.move(endX, endY, { steps: 10 });
    await page.mouse.up();
    await page.waitForTimeout(2000);

    // Wait for drawer and button to appear
    await page.waitForSelector('#visits-drawer.open', { timeout: 15000 });
    await page.waitForSelector('#delete-selection-button', { timeout: 15000 });

    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(2000);

    // Verify heatmap was updated
    const finalHeatmapCount = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.heatmapLayer?._latlngs?.length || 0;
    });

    expect(finalHeatmapCount).toBeLessThan(initialHeatmapCount);
  });

  test('should clear selection after successful deletion', async ({ page }) => {
    // Set up dialog handler to accept deletion
    page.on('dialog', async dialog => {
      await dialog.accept();
    });

    // Perform deletion using same selection logic as helper
    const selectionButton = page.locator('#selection-tool-button');
    await selectionButton.click();
    await page.waitForTimeout(500);

    const mapContainer = page.locator('#map [data-maps-target="container"]');
    const bbox = await mapContainer.boundingBox();

    // Use larger selection area to ensure we select points
    const startX = bbox.x + bbox.width * 0.2;
    const startY = bbox.y + bbox.height * 0.2;
    const endX = bbox.x + bbox.width * 0.8;
    const endY = bbox.y + bbox.height * 0.8;

    await page.mouse.move(startX, startY);
    await page.mouse.down();
    await page.mouse.move(endX, endY, { steps: 10 });
    await page.mouse.up();
    await page.waitForTimeout(2000);

    // Wait for drawer and button to appear
    await page.waitForSelector('#visits-drawer.open', { timeout: 15000 });
    await page.waitForSelector('#delete-selection-button', { timeout: 15000 });

    const deleteButton = page.locator('#delete-selection-button');
    await deleteButton.click();
    await page.waitForTimeout(2000);

    // Verify selection is cleared
    const isSelectionActive = await page.evaluate(() => {
      const controller = window.Stimulus?.controllers.find(c => c.identifier === 'maps');
      return controller?.visitsManager?.isSelectionActive === false &&
        controller?.visitsManager?.selectedPoints?.length === 0;
    });

    expect(isSelectionActive).toBe(true);

    // Verify buttons are removed
    await expect(page.locator('#cancel-selection-button')).not.toBeVisible();
    await expect(page.locator('#delete-selection-button')).not.toBeVisible();
  });
});
