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

// Setup: Create screenshots directory if it doesn't exist
const screenshotDir = 'screenshots';
fs.mkdirSync(screenshotDir, { recursive: true });

// Aisle coordinates (shared between tests)
const aisleCoordinates =  [
  { x: 191, y: 237 },
  { x: 271, y: 238 },
  { x: 301, y: 170, button: 'right' },
  { x: 191, y: 266 },
  { x: 270, y: 268 },
  { x: 377, y: 171, button: 'right' },
  { x: 188, y: 295 },
  { x: 270, y: 297 },
  { x: 335, y: 189, button: 'right' },
  { x: 187, y: 321 },
  { x: 267, y: 320 },
  { x: 341, y: 183, button: 'right' },
  { x: 190, y: 238 },
  { x: 189, y: 321 },
  { x: 240, y: 358, button: 'right' },
  { x: 351, y: 247 },
  { x: 425, y: 246 },
  { x: 426, y: 327 },
  { x: 346, y: 325 },
  { x: 350, y: 248 },
  { x: 372, y: 167, button: 'right' },
  { x: 491, y: 240 },
  { x: 577, y: 242 },
  { x: 577, y: 329 },
  { x: 490, y: 328 },
  { x: 489, y: 240 },
  { x: 478, y: 294, button: 'right' },
  { x: 489, y: 294 },
  { x: 577, y: 297 },
  { x: 386, y: 360, button: 'right' },
  { x: 193, y: 400 },
  { x: 194, y: 496 },
  { x: 250, y: 496 },
  { x: 251, y: 400 },
  { x: 191, y: 401 },
  { x: 301, y: 362, button: 'right' },
  { x: 346, y: 402 },
  { x: 386, y: 401 },
  { x: 387, y: 435 },
  { x: 344, y: 434 },
  { x: 343, y: 397 },
  { x: 309, y: 361, button: 'right' },
  { x: 340, y: 444 },
  { x: 387, y: 444 },
  { x: 387, y: 472 },
  { x: 339, y: 474 },
  { x: 341, y: 444 },
  { x: 338, y: 501, button: 'right' },
  { x: 337, y: 486 },
  { x: 386, y: 489 },
  { x: 386, y: 512 },
  { x: 339, y: 511 },
  { x: 336, y: 486 },
  { x: 419, y: 466, button: 'right' },
  { x: 484, y: 395 },
  { x: 577, y: 395 },
  { x: 580, y: 509 },
  { x: 484, y: 507 },
  { x: 484, y: 396 },
  { x: 471, y: 424, button: 'right' },
  { x: 484, y: 453 },
  { x: 576, y: 456 },
  { x: 669, y: 596, button: 'right' },
  { x: 715, y: 220 },
  { x: 789, y: 222 },
  { x: 793, y: 344 },
  { x: 711, y: 342 },
  { x: 714, y: 219 },
  { x: 759, y: 294, button: 'right' },
  { x: 713, y: 283 },
  { x: 790, y: 280 },
  { x: 844, y: 172, button: 'right' },
  { x: 931, y: 210 },
  { x: 934, y: 316 },
  { x: 996, y: 316 },
  { x: 998, y: 212 },
  { x: 930, y: 211 },
  { x: 1031, y: 212, button: 'right' },
  { x: 1012, y: 212 },
  { x: 1014, y: 316 },
  { x: 1074, y: 314 },
  { x: 1072, y: 210 },
  { x: 1010, y: 210 },
  { x: 1087, y: 210, button: 'right' },
  { x: 1091, y: 211 },
  { x: 1094, y: 315 },
  { x: 1172, y: 317 },
  { x: 1220, y: 285, button: 'right' },
  { x: 1090, y: 212 },
  { x: 1172, y: 214 },
  { x: 1173, y: 315 },
  { x: 1064, y: 359, button: 'right' },
  { x: 928, y: 368 },
  { x: 927, y: 457 },
  { x: 1022, y: 452 },
  { x: 1022, y: 371 },
  { x: 928, y: 374 },
  { x: 964, y: 417, button: 'right' },
  { x: 1094, y: 370 },
  { x: 1095, y: 456 },
  { x: 1186, y: 457 },
  { x: 1186, y: 374 },
  { x: 1095, y: 377 },
  { x: 1061, y: 500, button: 'right' },
  { x: 923, y: 535 },
  { x: 1022, y: 535 },
  { x: 1020, y: 627 },
  { x: 922, y: 628 },
  { x: 921, y: 534 },
  { x: 1059, y: 625, button: 'right' },
  { x: 1091, y: 537 },
  { x: 1185, y: 534 },
  { x: 1183, y: 627 },
  { x: 1089, y: 631 },
  { x: 1092, y: 536 },
  { x: 1079, y: 693, button: 'right' },
];

/**
 * Reusable function for creating or deleting aisles.
 * @param {Object} page - Playwright page object
 * @param {Array} coordinates - Array of {x, y, button?} objects representing aisle points
 * @param {String} action - 'create' or 'delete'
 */
async function drawOrDeleteAisles(page, coordinates, action) {
  console.log(`${action === 'create' ? 'Creating' : 'Deleting'} aisles...`);
  const startTime = Date.now(); // Start measuring time

  // Group coordinates into smaller batches to reduce overhead
  const batchSize = 10; // Adjust based on application performance
  for (let i = 0; i < coordinates.length; i += batchSize) {
    const batch = coordinates.slice(i, i + batchSize);

    // Process each batch
    for (const { x, y, button = 'left' } of batch) {
      console.log(`${action === 'create' ? 'Creating' : 'Deleting'} at (${x}, ${y})`);
      await simulatePointerClick(page, x, y, button);

      // Wait for the element to disappear (if applicable)
      if (action === 'delete') {
        try {
          await page.waitForSelector(`[data-aisle-coordinates="${x},${y}"]`, { state: 'hidden', timeout: 1000 });
        } catch (error) {
          console.warn(`Element at (${x}, ${y}) was not found or already deleted.`);
        }
      }
    }

    // Add a small delay after each batch to allow the application to catch up
    await page.waitForTimeout(500); // Reduced delay compared to individual clicks
  }

  // Finalize aisle creation with right-click (only for creation)
  if (action === 'create') {
    console.log('Finalizing aisle creation...');
    await simulatePointerClick(page, 100, 160, 'right'); // Right-click to finalize
  }

  // Log total time taken
  const endTime = Date.now();
  console.log(`Finished ${action === 'create' ? 'creating' : 'deleting'} aisles in ${(endTime - startTime) / 1000} seconds.`);
}

/**
 * Simulates a pointer click at specific coordinates.
 * @param {Object} page - Playwright page object
 * @param {Number} x - X-coordinate
 * @param {Number} y - Y-coordinate
 * @param {String} button - Mouse button ('left', 'right', or 'dblclick')
 */
async function simulatePointerClick(page, x, y, button = 'left') {
  // Move to the desired position
  await page.mouse.move(x, y);

  if (button === 'dblclick') {
    await page.mouse.dblclick(x, y);
  } else {
    // Simulate mouse down and up to mimic a real click
    await page.mouse.down({ button });
    await page.mouse.up({ button });
  }
}

/**
 * Common setup steps for both create and delete tests.
 * @param {Object} page - Playwright page object
 * @param {String} toolSelector - Selector for the tool to select (e.g., 'Aisle' or 'Delete')
 */
async function setupCanvasAndTools(page, toolSelector) {
  // 1. Navigate to the application
  await page.goto('http://185.100.212.76:8200');
  await page.getByPlaceholder('Email').fill('ramkumar@tester.local');
  await page.getByPlaceholder('Password').fill('123456');
  await page.getByRole('button', { name: 'Continue', exact: true }).click();

  // 2. Switch to full-screen mode
  console.log('Switching to full-screen mode...');
  await page.keyboard.press('F11'); // Simulate pressing F11 to enter full-screen mode

  // 3. Switch to 2D mode
  await page.locator('.toggle-option:has-text("2d")').click();

  // 4. Move the canvas to the top position
  console.log('Moving canvas to the top position...');
  const canvas = page.locator('canvas').first();
  const canvasBox = await canvas.boundingBox();
  if (!canvasBox) {
    throw new Error('Canvas bounding box not found. Ensure the canvas is visible.');
  }

  // Start position (center of canvas)
  const startX = canvasBox.x + canvasBox.width / 2;
  const startY = canvasBox.y + canvasBox.height / 2;

  // Simulate a drag action to move the canvas
  await page.mouse.move(startX, startY);
  await page.mouse.down();
  await page.mouse.move(startX, startY + 100, { steps: 20 }); // Smooth movement
  await page.mouse.wheel(0, 500); // Scroll down 500px
  await page.mouse.up();

  // 5. Select the appropriate tool (e.g., Aisle or Delete)
  console.log(`Selecting ${toolSelector === 'Aisle' ? 'Aisle' : 'Delete'} tool...`);
  if (toolSelector === 'Delete') {
    // Open the "3 dots" menu and select the Delete option
    await page.locator('.drop-down-option-button > svg').click();
    await page.locator('div').filter({ hasText: /^Delete$/ }).first().click();
  } else {
    // Select the Aisle tool
    await page.getByTitle(toolSelector).getByRole('img').click();
  }

  await page.waitForTimeout(2000); // Wait for the tool to be active
}

// Test 1: Create aisles after moving canvas
test('Create aisles after moving canvas', async ({ page }) => {
  // Increase the timeout for this test
  test.setTimeout(100000); // Set timeout to 100 seconds

  // Perform common setup
  await setupCanvasAndTools(page, 'Aisle');

  // Create aisles using reusable function
  await drawOrDeleteAisles(page, aisleCoordinates, 'create');

  // Take a final screenshot after creating aisles
  const afterCreationPath = `${screenshotDir}/aisles-created-after-moving-canvas.png`;
  await page.screenshot({ path: afterCreationPath });
  console.log(`Aisles created. Screenshot saved at: ${afterCreationPath}`);
});

// Test 2: Delete aisles after moving canvas
test('Delete aisles after moving canvas', async ({ page }) => {
  // Increase the timeout for this test
  test.setTimeout(100000); // Set timeout to 100 seconds

  // Perform common setup
  await setupCanvasAndTools(page, 'Delete');

  // Delete aisles using reusable function
  await drawOrDeleteAisles(page, aisleCoordinates, 'delete');

  // Take a final screenshot after deleting aisles
  const afterDeletionPath = `${screenshotDir}/aisles-deleted-after-moving-canvas.png`;
  await page.screenshot({ path: afterDeletionPath });
  console.log(`Aisles deleted. Screenshot saved at: ${afterDeletionPath}`);
});