import getSelector from '../../utilities/selector';
import { SELECT_TYPES } from './constants';

const BORDER_THICKNESS = 2;
const { EXTRACT_DATA, SELECT_NEXT_PAGE_SELECTOR, SELECT_PAGINATION_SELECTOR } = SELECT_TYPES;

export default class Tracker {
  constructor({ store } = {}) {
    this._overlay = null;
    this._selector = null;
    this._element = null;
    this._dimensions = {};
    this.currentSelector = '';
    this.store = store;

    this[EXTRACT_DATA] = null;
    this[SELECT_PAGINATION_SELECTOR] = null;
    this[SELECT_NEXT_PAGE_SELECTOR] = null;
  }

  startTracking = () => {
    if (!this._overlay) {
      this._overlay = document.createElement('div');
      this._overlay.id = 'headless-recorder-shooter';
      this._overlay.style.position = 'fixed';
      this._overlay.style.top = '0px';
      this._overlay.style.left = '0px';
      this._overlay.style.width = '100%';
      this._overlay.style.height = '100%';
      this._overlay.style.pointerEvents = 'none';
      this._overlay.style.zIndex = 2147483646;

      this._selector = document.createElement('div');
      this._selector.id = 'headless-recorder-shooter-outline';
      this._selector.style.position = 'fixed';
      this._overlay?.appendChild(this._selector);
    }

    if (!this._overlay.parentNode) {
      document.body?.appendChild(this._overlay);
      document.body.addEventListener('mousemove', this.mousemove);
      document.body.addEventListener('mouseover', this.mouseover);
      window.addEventListener('scroll', this._handleScroll, true);
    }
  };

  stopTracking = () => {
    if (this._overlay && document.body.contains(this._overlay)) {
      document?.body?.removeChild(this._overlay);
    }
    this._overlay = this._selector = this._element = null;
    this._dimensions = {};
    this.cleanup();
  };

  mouseover = (e) => {
    this.currentSelector = getSelector(e);
  };

  mousemove = (e) => {
    const elem = e instanceof Event ? e.target : e;

    if (
      this._element !== elem &&
      elem?.id !== 'custom-context-menu' &&
      elem?.id !== 'extract-data' &&
      elem?.id !== 'pagination-selector' &&
      elem?.id !== 'next-page-selector' &&
      elem?.id !== 'extract-field'
    ) {
      this._element = elem;

      this._dimensions.top = -window.scrollY;
      this._dimensions.left = -window.scrollX;

      let currentElem = elem;

      while (currentElem && currentElem !== document.body) {
        this._dimensions.top += currentElem.offsetTop;
        this._dimensions.left += currentElem.offsetLeft;
        currentElem = currentElem.offsetParent;
      }
      this._dimensions.width = this._element.offsetWidth;
      this._dimensions.height = this._element.offsetHeight;

      if (this._selector) {
        this._selector.style.top = this._dimensions.top - BORDER_THICKNESS + 'px';
        this._selector.style.left = this._dimensions.left - BORDER_THICKNESS + 'px';
        this._selector.style.width = this._dimensions.width + 'px';
        this._selector.style.height = this._dimensions.height + 'px';

        this._selector.style.border = `${BORDER_THICKNESS}px dashed rgba(255, 73, 73, 0.7)`;
        this._selector.style.background = 'rgba(255, 73, 73, 0.1)';
        this._selector.style.display = 'block';
      }
    }
  };

  cleanup() {
    document.body.removeEventListener('mousemove', this.mousemove);
    document.body.removeEventListener('mouseover', this.mouseover);
  }

  highlightSelector(elementTarget, color, text) {
    elementTarget.style.border = `${BORDER_THICKNESS}px dashed ${color}`;
    if (color === 'red') {
      elementTarget.style.background = 'rgba(255, 73, 73, 0.1)';
    } else if (color === 'blue') {
      elementTarget.style.background = 'rgba(0, 0, 255, 0.1)'; // Blue
    } else if (color === 'green') {
      elementTarget.style.background = 'rgba(0, 255, 0, 0.1)';
    }

    // Make sure the target element's position is not static
    if (window.getComputedStyle(elementTarget).position === 'static') {
      elementTarget.style.position = 'relative';
    }

    const textElement = document.createElement('div');
    textElement.style.position = 'absolute'; // Change from 'relative' to 'absolute'
    textElement.style.top = `-${BORDER_THICKNESS + 20}px`; // position it above the border
    textElement.style.left = `0px`; // align it with the left edge of the border
    textElement.style.color = color;
    textElement.style.zIndex = 2147483647; // to make sure it is on top of everything else
    textElement.textContent = text;
    elementTarget.appendChild(textElement); // Append the text element as a child of the target element
  }

  _handleScroll = () => {
    if (this._selector) {
      this._selector.style.display = 'none';
    }
  };
}
