import debounce from 'lodash/fp/debounce'
import escapeHtml from 'lodash/fp/escape'
import tldjs from 'tldjs'
import queryString from 'query-string'
import moment from 'moment'

import shortUrl from 'src/util/short-url'
import indexSearch from 'src/search'
import extractTimeFiltersFromQuery from 'src/util/nlp-time-filter'


// Read which browser we are running in.
let browserName
;(async () => {
    // XXX Firefox seems the only one currently implementing this function, but
    // luckily that is enough for our current needs.
    if (browser.runtime.getBrowserInfo !== undefined) {
        const browserInfo = await browser.runtime.getBrowserInfo()
        browserName = browserInfo.name
    }
})()

function formatTime(timestamp, showTime) {
    const m = moment(timestamp)
    const inLastSevenDays = moment().diff(m, 'days') <= 7

    if (showTime) {
        return inLastSevenDays ? `🕒 ${m.format('HH:mm a ddd')}` : `🕒 ${m.format('HH:mm a D/M/YYYY')}`
    }
    return inLastSevenDays ? m.format('ddd') : m.format('D/M/YYYY')
}

function setOmniboxMessage (text) {
    browser.omnibox.setDefaultSuggestion({
        description: text,
    })
}

const pageToSuggestion = timeFilterApplied => doc => {
    const url = escapeHtml(shortUrl(doc.url))
    const title = escapeHtml(doc.content.title)
    const time = formatTime(doc[doc.displayType], timeFilterApplied)

    return {
        content: doc.url,
        description: browserName === 'Firefox' ? `${url} ${title} - ${time}` : `<url>${url}</url> <dim>${title}</dim> - ${time}`,
    }
}

let currentQuery
let latestResolvedQuery
async function makeSuggestion(query, suggest) {
    currentQuery = query

    // Show no suggestions if there is no query.
    if (query.trim() === '') {
        setOmniboxMessage('Type to search your memory.')
        suggest([])
        latestResolvedQuery = query
        return
    }

    setOmniboxMessage('Searching your memory.. (press enter to search deeper)')

    const queryForOldSuggestions = latestResolvedQuery

    const {
        startDate,
        endDate,
        extractedQuery,
    } = extractTimeFiltersFromQuery(query)

    const searchResults = await indexSearch({
        query: extractedQuery,
        startDate,
        endDate,
        limit: 5,
        getTotalCount: true,
    })

    // A subsequent search could have already started and finished while we
    // were busy searching, so we ensure we do not overwrite its results.
    if (currentQuery !== query && latestResolvedQuery !== queryForOldSuggestions) { return }

    if (searchResults.isBadTerm === true) {
        setOmniboxMessage('Your search terms are very vague, please try and use more unique language')
    } else if (searchResults.docs.length === 0) {
        setOmniboxMessage('No results found in your memory. (press enter to search deeper')
    } else {
        setOmniboxMessage(`Found these ${searchResults.totalCount} pages in your memory: (press enter to search deeper)`)
    }

    const suggestions = searchResults.docs.map(pageToSuggestion(startDate || endDate))

    suggest(suggestions)
    latestResolvedQuery = query
}

const acceptInput = (text, disposition) => {
    // Checks whether the text is a suggested url
    const validUrl = tldjs.isValid(text)
    const {
        startDate,
        endDate,
        extractedQuery,
    } = extractTimeFiltersFromQuery(text)

    const params = queryString.stringify({ query: extractedQuery, startDate, endDate })
    const overviewPageWithQuery = `/overview/overview.html?${params}`

    const goToUrl = validUrl ? text : overviewPageWithQuery

    switch (disposition) {
        case 'currentTab':
            browser.tabs.update({url: goToUrl})
            break
        case 'newForegroundTab':
            browser.tabs.create({url: goToUrl})
            break
        case 'newBackgroundTab':
            browser.tabs.create({url: goToUrl, active: false})
            break
    }
}

browser.omnibox.onInputChanged.addListener(debounce(500)(makeSuggestion))
browser.omnibox.onInputEntered.addListener(acceptInput)

@@ -3123,143 +3123,184 @@
 %0A%7D%0A%0A
-const acceptInput = (text, disposition) =%3E %7B%0A    // Checks whether the text is a suggested url%0A    const validUrl = tldjs.isValid(text)
+/**%0A * @param %7Bstring%7D text The omnibar text input.%0A * @returns %7Bstring%7D Overview page URL with %60text%60 formatted as query string params.%0A */%0Aconst formOverviewQuery = text =%3E %7B
 %0A   
@@ -3303,32 +3303,24 @@
 %0A    const %7B
-%0A       
  startDate,%0A
@@ -3314,32 +3314,24 @@
 %7B startDate,
-%0A       
  endDate,%0A  
@@ -3323,32 +3323,24 @@
 te, endDate,
-%0A       
  extractedQu
@@ -3334,37 +3334,32 @@
 , extractedQuery
-,%0A   
  %7D = extractTime
@@ -3381,17 +3381,16 @@
 y(text)%0A
-%0A
     cons
@@ -3473,41 +3473,19 @@
  %7D)%0A
+%0A
     
-const overviewPageWithQuery =
+return
  %60/o
@@ -3521,37 +3521,192 @@
 s%7D%60%0A
-%0A    const goToUrl = validUrl
+%7D%0A%0Aconst acceptInput = (text, disposition) =%3E %7B%0A    // Either go to URL if input is valid URL, else form query for overview search using input terms%0A    const url = tldjs.isValid(text)
  ? t
@@ -3715,29 +3715,31 @@
 t : 
-o
+formO
 verview
-PageWithQuery
+Query(text)
 %0A%0A  
@@ -3819,36 +3819,29 @@
 abs.update(%7B
+ 
 url
-: goToUrl
+ 
 %7D)%0A         
@@ -3915,28 +3915,21 @@
 create(%7B
+ 
 url
-: goToUrl
+ 
 %7D)%0A     
@@ -4011,18 +4011,10 @@
 te(%7B
+ 
 u
-rl: goToU
 rl, 
@@ -4026,16 +4026,17 @@
 e: false
+ 
 %7D)%0A     

Stop running uneeded code on omnibar input enter