import { ItemType, ItemsBoxType } from 'src/types/kanban_types';
import GetNeighborObjects from './GetNeighborObjects';

const AddDragDropItemBehavior = (itemsBox: ItemsBoxType): void => {
  AddDropZone(itemsBox);

  const items: ItemType[] = itemsBox.getElement('items');
  for (const item of items) {
    item
      .on('sizer.dragstart', function () {
        const neighbors = GetNeighborObjects(item);
        if (neighbors[0]) {
          console.log('dragstart Above', neighbors[0].text);
        }
        if (neighbors[1]) {
          console.log('dragstart Below', neighbors[1].text);
        }
        console.log('Dragged Item: ', item.text);

        const previousItemsBox = item.getParentSizer();
        item.setData({
          itemsBox: previousItemsBox,
          index: previousItemsBox.getChildIndex(item),
        });
        previousItemsBox.remove(item);
      })
      .on(
        'sizer.dragend',
        function (
          pointer: Phaser.Input.Pointer,
          dragX: number,
          dragY: number,
          dropped: boolean,
        ) {
          if (dropped) {
            return;
          }

          const previousItemsBox = item.getData('itemsBox') as ItemsBoxType;
          previousItemsBox.insert(item.getData('index') as number, item, {
            expand: true,
          });
          ArrangeItems(previousItemsBox);
          const neighbors = GetNeighborObjects(item);
          if (neighbors[0]) {
            console.log('dragend Above', neighbors[0].text);
          }
          if (neighbors[1]) {
            console.log('dragend Below', neighbors[1].text);
          }
        },
      )
      .on(
        'sizer.drop',
        function (pointer: Phaser.Input.Pointer, dropZone: ItemType) {
          const currentItemsBox = dropZone.getData('itemsBox') as ItemsBoxType;
          const previousItemsBox = item.getData('itemsBox') as ItemsBoxType;

          currentItemsBox.insertAtPosition(
            pointer.x,
            pointer.y,
            item as unknown as Phaser.GameObjects.Text,
            {
              expand: true,
            },
          );

          ArrangeItems(previousItemsBox, currentItemsBox);
          const neighbors = GetNeighborObjects(item);
          if (neighbors[0]) {
            console.log('drop Above', neighbors[0].text);
          }
          if (neighbors[1]) {
            console.log('drop Below', neighbors[1].text);
          }
          console.log('Dragged Item: ', item.text);
        },
      );
  }
};

type InteractiveItemType = ItemType & {
  setInteractive: (options: { dropZone: boolean }) => void;
};

const AddDropZone = (itemsBox: ItemsBoxType): void => {
  const background = itemsBox.getElement(
    'background',
  ) as unknown as InteractiveItemType;
  if (background && typeof background.setInteractive === 'function') {
    background.setInteractive({ dropZone: true });
    background.setData('itemsBox', itemsBox);
  } else {
    console.error('Background is not defined or not interactive');
  }
};

const ArrangeItems = (
  itemsBox0: ItemsBoxType,
  itemsBox1?: ItemsBoxType,
): void => {
  const items: ItemType[] = [];
  items.push(...itemsBox0.getElement('items'));
  if (itemsBox1 && itemsBox0 !== itemsBox1) {
    items.push(...itemsBox1.getElement('items'));
  }

  for (const item of items) {
    item.setData({ startX: item.x, startY: item.y });
  }

  itemsBox0.getTopmostSizer().layout();

  for (const item of items) {
    const fromX = item.getData('startX') as number;
    const fromY = item.getData('startY') as number;
    if (item.x !== fromX || item.y !== fromY) {
      //@ts-ignore

      item.moveFrom({ x: fromX, y: fromY, duration: 300 });
    }
  }
};

export default AddDragDropItemBehavior;
