self.onmessage = function(e) {
  const { tokenBounds, tileBounds, tileTexture, chunkSize } = e.data;

  console.log('tokenBounds, tileBounds, tileTexture, chunkSize :>> ', tokenBounds, tileBounds, tileTexture, chunkSize);

  // Calculate intersection area
  const x = Math.max(tokenBounds.x, tileBounds.x);
  const y = Math.max(tokenBounds.y, tileBounds.y);
  const width = Math.min(tokenBounds.x + tokenBounds.width, tileBounds.x + tileBounds.width) - x;
  const height = Math.min(tokenBounds.y + tokenBounds.height, tileBounds.y + tileBounds.height) - y;

  // Skip if no intersection
  if (width <= 0 || height <= 0) {
      self.postMessage({ type: 'noIntersection' });
      return;
  }

  // Set canvas size to intersection size
  const tempCanvas = new OffscreenCanvas(Math.ceil(width), Math.ceil(height));
  const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });

  // Calculate source and destination rectangles
  const sourceX = (x - tileBounds.x) * (tileTexture.width / tileBounds.width);
  const sourceY = (y - tileBounds.y) * (tileTexture.height / tileBounds.height);
  const sourceWidth = width * (tileTexture.width / tileBounds.width);
  const sourceHeight = height * (tileTexture.height / tileBounds.height);

  // Clear the canvas and Draw the relevant portion of the tile
  tempCtx.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
  tempCtx.drawImage(tileTexture,
      sourceX, sourceY, sourceWidth, sourceHeight,
      0, 0, tempCanvas.width, tempCanvas.height
  );

  // Get image data for the intersection area
  const imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
  const dataU32 = new Uint32Array(imageData.data.buffer);

  const width32 = tempCanvas.width;
  const height32 = tempCanvas.height;

  const chunks = [];

  for (let cy = 0; cy < height32; cy += chunkSize) {
      for (let cx = 0; cx < width32; cx += chunkSize) {
          let hasOpaquePixel = false;

          // Check the chunk for any non-transparent pixels
          chunkCheck: for (let by = 0; by < chunkSize; by++) {
              const y = cy + by;
              if (y >= height32) break;

              for (let bx = 0; bx < chunkSize; bx++) {
                  const x = cx + bx;
                  if (x >= width32) break;

                  const pixelIndex = y * width32 + x;
                  const alphaValue = dataU32[pixelIndex] >>> 24;

                  if (alphaValue > 0) {
                      hasOpaquePixel = true;
                      break chunkCheck;
                  }
              }
          }

          // If chunk has any non-transparent pixels, add it to the list
          if (hasOpaquePixel) {
              chunks.push({
                  x: x + cx,
                  y: y + cy,
                  width: Math.min(chunkSize, width32 - cx),
                  height: Math.min(chunkSize, height32 - cy)
              });
          }
      }
  }

  self.postMessage({ type: 'chunks', chunks });
};