import browserPackage from '@utils/helpers/browserPackage'
import { urlMatcher } from '@utils/helpers/urlMatcher'
import navigationRef from '@utils/navigation/navigationRef'
import { queryClient } from '@utils/queryHooks'
import { QueryKeyAccount } from '@utils/queryHooks/account'
import { searchLocalAccount, searchLocalStatus } from '@utils/queryHooks/search'
import { QueryKeyStatus } from '@utils/queryHooks/status'
import { getGlobalStorage } from '@utils/storage/actions'
import * as Linking from 'expo-linking'
import * as WebBrowser from 'expo-web-browser'
import { WebBrowserPresentationStyle } from 'expo-web-browser'

const openLink = async (url: string, navigation?: any) => {
  const handleNavigation = (page: 'Tab-Shared-Toot' | 'Tab-Shared-Account', options: any) => {
    if (navigation) {
      navigation.push(page, options)
    } else {
      // @ts-ignore
      navigationRef.navigate(page, options)
    }
  }

  const match = urlMatcher(url)
  // If a tooot can be found
  if (match?.status?.id) {
    let response: Mastodon.Status | undefined = undefined

    const queryKey: QueryKeyStatus = [
      'Status',
      { id: match.status.id, uri: url, _remote: match.status._remote }
    ]
    const cache = queryClient.getQueryData<Mastodon.Status>(queryKey)

    if (cache) {
      handleNavigation('Tab-Shared-Toot', { toot: cache })
      return
    } else {
      try {
        response = await searchLocalStatus(url, true)
      } catch {}
      if (response) {
        handleNavigation('Tab-Shared-Toot', { toot: response })
        return
      }
    }
  }

  // If an account can be found
  if (match?.account) {
    let response: Mastodon.Account | undefined = undefined

    const queryKey: QueryKeyAccount = ['Account', { url: url, _remote: match.account._remote }]
    const cache = queryClient.getQueryData<Mastodon.Status>(queryKey)

    if (cache) {
      handleNavigation('Tab-Shared-Account', { account: cache })
      return
    } else {
      try {
        response = await searchLocalAccount(url, true)
      } catch {}
      if (response) {
        handleNavigation('Tab-Shared-Account', { account: response })
        return
      }
    }
  }

  // Some links might end with an empty space at the end that triggers an error
  switch (getGlobalStorage.string('app.browser')) {
    case 'external':
      await Linking.openURL(url.trim())
      break
    case 'internal':
    default:
      await WebBrowser.openBrowserAsync(url.trim(), {
        dismissButtonStyle: 'close',
        presentationStyle: WebBrowserPresentationStyle.AUTOMATIC,
        enableBarCollapsing: true,
        ...(await browserPackage())
      }).catch(() => Linking.openURL(url.trim()))
      break
  }
}

export default openLink
