import type { NodeViewMode, TraceViewMode } from '@/stores/uiStore'
import packageInfo from '../../package.json'

const version = packageInfo.version

enum EventName {
  // traces management
  PasteNewTrace = 'trace-explorer-paste-new-trace',
  AddTrace = 'trace-explorer-add-trace',
  CancelPasteTrace = 'trace-explorer-cancel-paste-trace',
  ReloadTraces = 'trace-explorer-reload-traces',
  // trace view change
  TreeTraceViewChange = 'trace-explorer-tree-trace-view-change',
  TimelineTraceViewChange = 'trace-explorer-timeline-trace-view-change',
  ExplorerTraceViewChange = 'trace-explorer-explorer-trace-view-change',
  ResetView = 'trace-explorer-reset-view',
  // node view change
  FormattedNodeViewChange = 'trace-explorer-formatted-node-view-change',
  RawNodeViewChange = 'trace-explorer-raw-node-view-change',
  // explore traces & nodes
  SelectTrace = 'trace-explorer-select-trace',
  FilterTraces = 'trace-explorer-filter-trace',
  SearchNodes = 'trace-explorer-search-nodes',
  SearchTraces = 'trace-explorer-search-traces',
  SortExplorerNodes = 'trace-explorer-sort-explorer-nodes',
  // expand & highlight nodes
  OpenNodeDetails = 'trace-explorer-open-node-details',
  HighlightNodes = 'trace-explorer-highlight-node',
  // error
  Error = 'trace-explorer-error', // error
  // settings
  ThemeChange = 'trace-explorer-theme-change',
}

export class WT1iser {
  private static webappVersion = version

  /* traces management */

  static pasteNewTrace() {
    this.sendEvent(EventName.PasteNewTrace, {})
  }

  static addTrace() {
    this.sendEvent(EventName.AddTrace, {})
  }

  static cancelPasteTrace() {
    this.sendEvent(EventName.CancelPasteTrace, {})
  }

  static reloadTraces() {
    this.sendEvent(EventName.ReloadTraces, {})
  }

  /* tabs & view change */

  static tabChange(traceViewMode: TraceViewMode) {
    if (traceViewMode === 'tree') {
      this.sendEvent(EventName.TreeTraceViewChange, {})
    } else if (traceViewMode === 'timeline') {
      this.sendEvent(EventName.TimelineTraceViewChange, {})
    } else if (traceViewMode === 'explorer') {
      this.sendEvent(EventName.ExplorerTraceViewChange, {})
    }
  }

  static resetView(viewMode: TraceViewMode) {
    this.sendEvent(EventName.ResetView, { viewMode: viewMode })
  }

  /* node view change */

  static nodeViewChange(nodeViewMode: NodeViewMode) {
    if (nodeViewMode === 'formatted') {
      this.sendEvent(EventName.FormattedNodeViewChange, {})
    } else if (nodeViewMode === 'raw') {
      this.sendEvent(EventName.RawNodeViewChange, {})
    }
  }

  /* explore traces & nodes */

  static selectTrace(traceId: string) {
    this.sendEvent(EventName.SelectTrace, { traceId })
  }

  static filterTraces(nameFilter: string, durationRange: string, dateFrom: string, dateTo: string) {
    this.sendEvent(EventName.FilterTraces, {
      nameFilter,
      durationRange,
      dateFrom,
      dateTo,
    })
  }

  static searchNodes(query: string) {
    this.sendEvent(EventName.SearchNodes, { query })
  }

  static searchTraces(nameQuery: string, resultQuery: string) {
    this.sendEvent(EventName.SearchTraces, { nameQuery, resultQuery })
  }

  static sortExplorerNodes(sorters: any) {
    this.sendEvent(EventName.SortExplorerNodes, { sorters })
  }

  static openNodeDetails(nodeId: string) {
    this.sendEvent(EventName.OpenNodeDetails, { nodeId })
  }

  static highlightNodes(group: string) {
    this.sendEvent(EventName.HighlightNodes, { group })
  }

  /* error */

  static error(actionName: string, nQuestions: number, error: string): void {
    this.sendEvent(EventName.Error, { actionName, nQuestions, error })
  }

  /* settings */

  static themeChange(theme: 'light' | 'dark' | 'auto') {
    this.sendEvent(EventName.ThemeChange, { theme })
  }

  static init() {
    console.log('** trace explorer version **', version)
    try {
      if (!(window.parent as any).WT1SVC && (window as any).dkuUsageReportingUtils) {
        console.debug('bootstrap standalone reporting mode')
        ;(window as any).dkuUsageReportingUtils.standaloneModeBootstrap()
      }
    } catch (error) {
      console.error('Error in WT1iser.init', error)
    }
  }

  private static prepareEventParams(props: any) {
    return {
      ...props,
      webappVersion: this.webappVersion,
    }
  }

  private static sendEvent(event: EventName, props: any) {
    try {
      const params = this.prepareEventParams(props)
      if ((window.parent as any).WT1SVC) {
        ;(window.parent as any).WT1SVC.event(event, params)
      } else if ((window as any).dkuUsageReportingUtils) {
        ;(window as any).dkuUsageReportingUtils.standaloneModeTrackEvent(event, params)
      }
    } catch (error) {
      console.error('Error in WT1iser.sendEvent', error)
    }
  }
}
