import {
  EVENT_WEBVIEW_MESSAGE,
  EVENT_WEBVIEW_DATA,
  NOTIFICATION_WEBVIEW,
  ALERT_PARAMS,
  WEBVIEW_ERROR_MESSAGE_TYPE,
  WEBVIEW_ERROR_MESSAGE_TX
} from 'constants/webview'
import { EXPERIENCE_TYPE, Experience } from 'redux/Experience/types'

interface IRNWebView {
  trackStep: (step: number) => any
  trackLoadingStage: (isLoading: boolean) => any
  done: () => any
  registrationTalentCompleted: () => any
  selectContentType: (contentType: EXPERIENCE_TYPE | undefined) => any
  notification: (message: NOTIFICATION_WEBVIEW) => any
  openWebBrowser: (webBrowser: string) => any
  alert: (params: ALERT_PARAMS) => any
  recordExpData: (experienceData: {
    id: string | undefined
    data: Experience
  }) => any
  logErrorMessage: (
    message: WEBVIEW_ERROR_MESSAGE_TX | undefined,
    type: WEBVIEW_ERROR_MESSAGE_TYPE
  ) => any
}
const rules = [
  // if it says it's a webview, let's go with that
  'WebView',
  // iOS webview will be the same as safari but missing "Safari"
  '(iPhone|iPod|iPad)(?!.*Safari)',
  // Android Lollipop and Above: webview will be the same as native but it will contain "wv"
  // Android KitKat to lollipop webview will put {version}.0.0.0
  'Android.*(wv|.0.0.0)',
  // old chrome android webview agent
  'Linux; U; Android'
]

class WebViewMessage implements IRNWebView {
  protected ele: any

  constructor(ele: any) {
    this.ele = ele
  }

  private postMessage = (
    message: EVENT_WEBVIEW_MESSAGE,
    data?: EVENT_WEBVIEW_DATA
  ) => {
    this.ele?.ReactNativeWebView?.postMessage(
      JSON.stringify({ message, data: data && JSON.stringify(data) })
    )
  }

  public isWebView = (): boolean => {
    const webviewRegExp = new RegExp('(' + rules.join('|') + ')', 'ig')
    const userAgent = window.navigator.userAgent.toLowerCase()

    return !!userAgent.match(webviewRegExp)
  }

  public trackStep = (step: number): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.STEP_TRACK, { step })
  }

  public trackLoadingStage = (isLoading: boolean): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.LOADING, { isLoading })
  }

  public done = () => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.DONE)
  }

  public registrationTalentCompleted = () => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.REGISTRATION_TALENT_COMPLETED)
  }

  public selectContentType = (
    contentType: EXPERIENCE_TYPE | undefined
  ): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.SELECT_COTENT_TYPE, { contentType })
  }

  public notification = (message: NOTIFICATION_WEBVIEW): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.NOTIFICATION, {
      notification: message
    })
  }

  public openWebBrowser = (webBrowser: string): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.OPEN_WEB_BROWSER, {
      webBrowser
    })
  }

  public alert = (alert: ALERT_PARAMS): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.ALERT, {
      alert
    })
  }

  public recordExpData = (experienceData: {
    id: string | undefined
    data: Experience
  }): void => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.RECORD_EXP_DATA, {
      experienceData: {
        id: experienceData?.id,
        data: experienceData?.data
      }
    })
  }

  public logErrorMessage = (
    message: WEBVIEW_ERROR_MESSAGE_TX | undefined,
    type: WEBVIEW_ERROR_MESSAGE_TYPE
  ) => {
    this.postMessage(EVENT_WEBVIEW_MESSAGE.LOG_ERROR_MESSAGE, {
      errorMessage: {
        [type]: message
      }
    })
  }
}

export const webviewMessage = new WebViewMessage(window)
