import { isEqual } from 'lodash';
import getSelector from '../../utilities/selector';
import { HIGHTLIGHT_TYPES } from '../highlight/constants';

export default class ContextMenu {
  constructor({ store }) {
    this._menu = null;
    this.store = store;
    this.actionMap = this._getActionMap();
    this.removeSelectorType = null;
  }

  _getActionMap = () => {
    return {
      extractDataOption: (e) => {
        this._addHighlightingSelector(HIGHTLIGHT_TYPES.EXTRACT_TABLE, e);
        // this.store.updateSelectors(HIGHTLIGHT_TYPES.EXTRACT_TABLE, getSelector(e));
      },
      extractPaginationOption: (e) => {
        this._addHighlightingSelector(HIGHTLIGHT_TYPES.EXTRACT_PAGINATION, e);
        // this.store.updateSelectors(HIGHTLIGHT_TYPES.EXTRACT_PAGINATION, getSelector(e));
      },
      extractNextPageOption: (e) => {
        this._addHighlightingSelector(HIGHTLIGHT_TYPES.EXTRACT_NEXT_PAGE, e);
        // this.store.updateSelectors(HIGHTLIGHT_TYPES.EXTRACT_NEXT_PAGE, getSelector(e));
      },
      extractField: (e) => {
        this._addHighlightingSelector(HIGHTLIGHT_TYPES.EXTRACT_FIELD, e);
        // this.store.updateSelectors(HIGHTLIGHT_TYPES.EXTRACT_FIELD, getSelector(e));
      },
      removeSelector: (e) => {
        const { isTableMode, hightLightingSelectors } = this.store.getState();
        const selector = getSelector(e);
        if (this.removeSelectorType) {
          this.store.updateSelectors(
            this.removeSelectorType,
            isTableMode ? '' : hightLightingSelectors?.filter((item) => item.selector !== selector),
          );
          this.store.removeHighlightedSelector(this.removeSelectorType, selector);
        }
      },
    };
  };

  _addHighlightingSelector = (type, e) => {
    this.store.addHighlightingSelector(type, getSelector(e));
  };

  init = () => {
    document.body.addEventListener('contextmenu', this._handleContextMenu, true);
    window.addEventListener('click', this._removeMenu, true);
  };

  destroy = () => {
    document.body.removeEventListener('contextmenu', this._handleContextMenu, true);
  };

  _handleContextMenu = (e) => {
    e.preventDefault();
    this._removeExistingMenu();
    this._createMenu(e);
  };

  _removeExistingMenu = () => {
    const existingMenu = document.getElementById('custom-context-menu');
    if (existingMenu) {
      existingMenu.remove();
    }
  };

  _removeMenu = () => {
    if (this._menu) {
      this._menu.remove();
    }
  };

  _createMenu = (e) => {
    this._menu = this._createMenuElement(e);
    this._menu.addEventListener('click', (event) => this._handleMenuClick(event, e));
    ['mousemove', 'mouseover'].forEach((eventType) => {
      this._menu.addEventListener(eventType, this._stopEventPropagation);
    });
    this._populateMenuOptions(e);
  };

  _createMenuElement = (e) => {
    const menu = document.createElement('div');
    menu.id = 'custom-context-menu';
    menu.style.position = 'fixed';
    menu.style.top = `${e.clientY}px`;
    menu.style.left = `${e.clientX}px`;
    menu.style.backgroundColor = '#ffffff';
    menu.style.border = '1px solid #dddddd';
    menu.style.padding = '5px 10px';
    menu.style.zIndex = 2147483647;
    menu.style.cursor = 'pointer';
    menu.style.fontSize = '14px';
    menu.style.display = 'flex';
    menu.style.flexDirection = 'column';
    menu.style.gap = '10px';
    return menu;
  };

  _handleMenuClick = (event, e) => {
    event.stopPropagation();
    event.preventDefault();
    const action = this.actionMap[event?.target?.id];
    if (action) {
      action(e);
      this._removeMenu();
    }
  };

  _stopEventPropagation = (e) => {
    e.stopPropagation();
  };

  _populateMenuOptions = (e) => {
    const { hightLightingSelectors, isTableMode } = this.store.getState();
    const selector = getSelector(e);
    const { extractTableSelector, paginationSelector, nextPageSelector } = this._getSelectors(hightLightingSelectors);
    if (isTableMode) {
      this._populateTableModeOptions({ extractTableSelector, paginationSelector, nextPageSelector });
    } else {
      this._createOption('extractField', 'Extract Field');
    }
    if (
      this._shouldCreateRemoveSelectorOption({
        hightLightingSelectors,
        extractTableSelector,
        paginationSelector,
        nextPageSelector,
        selector,
      })
    ) {
      this._createOption('removeSelector', 'Remove Selector');
    }
    if (this._menu.hasChildNodes()) {
      document.body?.appendChild(this._menu);
    } else {
      this._removeMenu();
    }
  };

  _getSelectors = (hightLightingSelectors) => {
    let extractTableSelector, paginationSelector, nextPageSelector;
    hightLightingSelectors.map((selector) => {
      if (isEqual(selector.type, HIGHTLIGHT_TYPES.EXTRACT_TABLE)) {
        extractTableSelector = selector;
      }
      if (isEqual(selector.type, HIGHTLIGHT_TYPES.EXTRACT_PAGINATION)) {
        paginationSelector = selector;
      }
      if (isEqual(selector.type, HIGHTLIGHT_TYPES.EXTRACT_NEXT_PAGE)) {
        nextPageSelector = selector;
      }
    });
    return { extractTableSelector, paginationSelector, nextPageSelector };
  };

  _populateTableModeOptions = ({ extractTableSelector, paginationSelector, nextPageSelector }) => {
    if (!extractTableSelector) {
      this._createOption('extractDataOption', 'Extract Data');
    } else if (!paginationSelector) {
      this._createOption('extractPaginationOption', 'Extract Pagination Selector');
    } else if (!nextPageSelector) {
      this._createOption('extractNextPageOption', 'Extract Next Page Selector');
    }
  };

  _shouldCreateRemoveSelectorOption = ({
    hightLightingSelectors,
    extractTableSelector,
    paginationSelector,
    nextPageSelector,
    selector,
  }) => {
    let shouldRemoveSelector = false;
    if (hightLightingSelectors.length > 0) {
      if (extractTableSelector?.selector === selector) {
        this.removeSelectorType = HIGHTLIGHT_TYPES.EXTRACT_TABLE;
        shouldRemoveSelector = true;
      } else if (paginationSelector?.selector === selector) {
        this.removeSelectorType = HIGHTLIGHT_TYPES.EXTRACT_PAGINATION;
        shouldRemoveSelector = true;
      } else if (nextPageSelector?.selector === selector) {
        this.removeSelectorType = HIGHTLIGHT_TYPES.EXTRACT_NEXT_PAGE;
        shouldRemoveSelector = true;
      } else if (hightLightingSelectors.some((item) => item.selector === selector)) {
        this.removeSelectorType = HIGHTLIGHT_TYPES.EXTRACT_FIELD;
        shouldRemoveSelector = true;
      }
    }
    return shouldRemoveSelector;
  };

  _createOption = (id, text) => {
    const option = document.createElement('div');
    option.id = id;
    option.innerText = text;
    this._menu.appendChild(option);
  };
}
