import browser from 'webextension-polyfill'

import { getLocalStorage, setLocalStorage } from 'src/util/storage'
import * as constants from './constants'

export const delayed = (f, delay) => {
    let timeout = null
    const clear = () => {
        timeout && clearTimeout(timeout)
        timeout = null
    }

    return (...args) => {
        clear()
        timeout = setTimeout(() => {
            f(...args)
            clear()
        }, delay)
    }
}

export const getExtURL = (location) =>
    browser.runtime ? browser.runtime.getURL(location) : location

export const getTooltipState: () => Promise<boolean> = async () =>
    await getLocalStorage(
        constants.TOOLTIP_STORAGE_NAME,
        constants.TOOLTIP_DEFAULT_OPTION,
    )

export const getHighlightsState: () => Promise<boolean> = async () =>
    await getLocalStorage(
        constants.HIGHLIGHTS_STORAGE_NAME,
        constants.HIGHLIGHTS_DEFAULT_OPTION,
    )

export const setHighlightsState = async (
    highlightsValue: boolean,
): Promise<void> =>
    setLocalStorage(constants.HIGHLIGHTS_STORAGE_NAME, highlightsValue)

export const setTooltipState = async (tooltipValue: boolean): Promise<void> =>
    setLocalStorage(constants.TOOLTIP_STORAGE_NAME, tooltipValue)

export const getPositionState = async () =>
    getLocalStorage(
        constants.POSITION_STORAGE_NAME,
        constants.POSITION_DEFAULT_OPTION,
    )

export const setPositionState = async (positionValue) =>
    setLocalStorage(constants.POSITION_STORAGE_NAME, positionValue)

/**
 * Sets up a callback to run on content script shutdown (when a new script starts up).
 * More info: https://stackoverflow.com/questions/25840674/chrome-runtime-sendmessage-throws-exception-from-content-script-after-reloading/25844023#25844023
 */
export function runOnScriptShutdown(callback) {
    const destroyEvent = `destroy-${browser.runtime.id}`
    document.dispatchEvent(new CustomEvent(destroyEvent))

    document.addEventListener(destroyEvent, function () {
        document.removeEventListener(destroyEvent, this)
        callback()
    })
}
