import { createSelector } from 'reselect';
import { generateId } from './utils';

const getTiles = (state) => state.tiles;
const getTile = (state, props) => state.tiles[props.id];
const getTurn = (state) => state.turn;
const getMoveCount = (state) => state.moveCount;
const getDraggedTileId = (state) => state.draggedTileId;
const getX = (state, props) => props.x;
const getY = (state, props) => props.y;

function tileOnBoard(tile) {
  return (typeof tile.x === 'number' && typeof tile.y === 'number');
}

function listAdjancentPositions(x, y) {
  let positions = [
    {x: x + 1, y: y},
    {x: x - 1, y: y},
    {x: x, y: y + 1},
    {x: x, y: y - 1}
  ];

  if (x % 2) {
    positions.push({x: x + 1, y: y + 1});
    positions.push({x: x - 1, y: y + 1});
  } else {
    positions.push({x: x + 1, y: y - 1});
    positions.push({x: x - 1, y: y - 1});
  }
  return positions;
}

export const canDropTile = createSelector(
  [getTiles, getTurn, getMoveCount, getDraggedTileId, getX, getY],
  (tiles, turn, moveCount, draggedTileId, x, y) => {
    const draggedTile = tiles[draggedTileId];
    if (moveCount === 0)
      return true;
    return listAdjancentPositions(x, y).some(pos => {
      return Object.keys(tiles).some(id => {
        let tile = tiles[id];
        if (tile.x === pos.x && tile.y === pos.y) {
          if (!draggedTile) {
            return false;
          }
          if (moveCount === 1) {
            return true;
          }
          if (!tileOnBoard(draggedTile)) {
            return tile.color == turn;
          }
          return true; // Tile movement rules go here
        }
      });
    });
  }
);

export const canDragTile = createSelector(
  [getTile, getTurn, getMoveCount, getTiles],
  (tile, turn, moveCount, tiles) => {
    if (tile.color !== turn)
      return false;
    if ((moveCount >= 4) && (!tileOnBoard(tiles[generateId(turn, 'bee', 0)])) && (tile.type !== 'bee')) {
      return false;
    }
    return true;
  }
);

export const getUsedTiles = createSelector(
  [getTiles],
  (tiles) => {
    let usedTiles = [];
    Object.keys(tiles).forEach((id) => {
      let tile = tiles[id];
      if (tileOnBoard(tile)) {
        usedTiles.push(tile);
      }
    });
    return usedTiles;
  }
);

const getUnusedColorTiles = (color) => createSelector(
  [getTiles],
  (tiles) => {
    let colorTiles = [];
    Object.keys(tiles).forEach((id) => {
      let tile = tiles[id];
      if (!tileOnBoard(tile)) {
        if (tile.color === color) {
          colorTiles.push(tile);
        }
      }
    });
    return colorTiles;
  }
);

export const getUnusedWhiteTiles = getUnusedColorTiles('white');
export const getUnusedBlackTiles = getUnusedColorTiles('black');

@@ -1079,24 +1079,74 @@
 gedTileId%5D;%0A
+    if (!draggedTile) %7B%0A      return false;%0A    %7D%0A
     if (move
@@ -1157,16 +1157,18 @@
 t === 0)
+ %7B
 %0A      r
@@ -1183,22 +1183,84 @@
 ue;%0A    
-return
+%7D%0A    let hasNeighbor = false;%0A    let hasColorNeighbor = false;%0A   
  listAdj
@@ -1281,20 +1281,23 @@
 s(x, y).
-some
+forEach
 (pos =%3E 
@@ -1304,23 +1304,43 @@
 %7B%0A      
-return 
+const neighborTile = tiles%5B
 Object.k
@@ -1354,12 +1354,12 @@
 es).
-some
+find
 (id 
@@ -1367,34 +1367,30 @@
 %3E %7B%0A        
-let tile =
+return
  tiles%5Bid%5D;%0A
@@ -1391,26 +1391,22 @@
 %5Bid%5D
-;%0A        if
+ &&
  (tile
+s%5Bid%5D
 .x =
@@ -1417,24 +1417,29 @@
 os.x && tile
+s%5Bid%5D
 .y === pos.y
@@ -1439,23 +1439,28 @@
 = pos.y)
- %7B
 %0A    
+  %7D)%5D;%0A
       if
@@ -1454,39 +1454,40 @@
 %7D)%5D;%0A      if (!
-dragged
+neighbor
 Tile) %7B%0A        
@@ -1490,32 +1490,22 @@
     
-    
 return
- false
 ;%0A      
     
@@ -1504,90 +1504,247 @@
     
+%7D%0A
     
-%7D%0A          if (moveCount === 1) %7B%0A            return true;%0A          %7D%0A      
+  hasNeighbor = true;%0A%0A      if (neighborTile.color == turn) %7B%0A        hasColorNeighbor = true;%0A      %7D%0A      return true;%0A    %7D);%0A    if (!hasNeighbor) %7B%0A      return false;%0A    %7D%0A    if (moveCount === 1) %7B%0A      return true;%0A    %7D%0A
     
@@ -1772,30 +1772,24 @@
 gedTile)) %7B%0A
-      
       return
@@ -1793,62 +1793,35 @@
 urn 
-tile.color == turn;%0A          %7D%0A          return true;
+hasColorNeighbor;%0A    %7D%0A   
  // 
@@ -1856,30 +1856,20 @@
     
-    %7D%0A      %7D);%0A    %7D)
+return false
 ;%0A  

Drop roue refactor