import config from "../../config";
import Component, { IComponent, IComponentOptions, IComponentSelector } from "../core/Component";
import { $ } from "../core/JDom";
import isMobile from "../utils/isMobile";
import isTouchDevice from "../utils/isTouchDevice";

declare global {
    interface Window {
        tooltipDocumentHandler?: boolean;
    }
}

const selectors = {
    element: `.${config.prefix}-tooltip`,
    content: `.${config.prefix}-tooltip-content`,
    wrapper: `.${config.prefix}-tooltip-wrapper`,
    header: `.${config.prefix}-tooltip-header`
}

interface ITooltipSelector extends IComponentSelector {
    content: string
    wrapper: string
    header: string
}

interface ITooltipOptions extends IComponentOptions {

}

interface ITooltip extends IComponent {
    selectors?: ITooltipSelector,
    options?: ITooltipOptions
}

class Tooltip extends Component {
    constructor(props: ITooltip = {}) {
        super({
            ...props,
            Component: Tooltip,
            selectors: Object.assign(selectors, props.selectors || {})
        })


        if (this.options && this.options.mount) {
            this.mount()
        }
    }

    mount() {
        if (!this.$element || this._mount || this.$element.get().hasAttribute('data-mount')) return;
        super.mount()

        this.options = Object.assign({}, this.options)

        this.handlers = {
            mouseOverHandler: this.mouseOverHandler.bind(this),
            mouseOutHandler: this.mouseOutHandler.bind(this),
            clickHandler: this.clickHandler.bind(this),
            documentHandler: this.documentHandler.bind(this),
        }

        this.addEvents()

        this.on.mount(this)
        this.emitter.emit('mount', this)
    }

    addEvents() {
        if (isMobile() || isTouchDevice()) {
            this.$element.get().addEventListener('click', this.handlers.clickHandler);

            if (!window.tooltipDocumentHandler) {
                window.tooltipDocumentHandler = true;
                document.addEventListener('click', this.handlers.documentHandler);
            }
        } else {
            this.$element.get().addEventListener('mouseover', this.handlers.mouseOverHandler)
            this.$element.get().addEventListener('mouseout', this.handlers.mouseOutHandler)
        }
    }

    mouseOverHandler() {

        this.$element.toggleAttribute('data-active')
        this.on.render(this)
        this.emitter.emit('render', this)
    }

    mouseOutHandler() {
        this.$element.get().removeAttribute('data-active')
        this.on.destroy(this)
        this.emitter.emit('destroy', this)
    }

    clickHandler() {
        this.$element.toggleAttribute('data-active')

        if (this.$element.get().hasAttribute('data-active')) {
            this.on.render(this)
            this.emitter.emit('render', this)
        } else {
            this.on.destroy(this)
            this.emitter.emit('destroy', this)
        }
    }

    documentHandler(e: Event) {
        if (!(e.target as HTMLElement).closest(selectors.element)) {
            $(selectors.element).attr('data-active', null)
        }
    }

    unmount() {
        super.unmount()

        this.$element.get().removeEventListener('mouseover', this.handlers.mouseOverHandler)
        this.$element.get().removeEventListener('mouseout', this.handlers.mouseOutHandler)
        this.$element.get().removeEventListener('click', this.handlers.clickHandler)

        this.on.unmount(this)
        this.emitter.emit('unmount', this)
    }
}

export default Tooltip