import Vue from 'vue'
import type { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'
import { VNode } from 'vue/types/umd'
import { MonitorElementData, MonitorReportData } from '.'

interface MonitorComponentProps {
  monitor?: MonitorElementData
  monitorExtra?: MonitorReportData['params']
}

export const MonitorComponent: ThisTypedComponentOptionsWithRecordProps<
  Vue,
  unknown,
  unknown,
  unknown,
  MonitorComponentProps
> = {
  name: 'MonitorComponent',

  props: {
    monitor: {
      type: Object,
    },
    monitorExtra: {
      type: Object,
    },
  },
  render() {
    const slots = this.$slots.default

    if (this.monitor) {
      slots?.forEach((slot) => {
        const Ctor: any = slot.componentOptions?.Ctor
        const options = Ctor.options
        const superOptions = Ctor.superOptions

        if (options.directives.monitor || superOptions.directives.monitor) {
          const data = slot.data || (slot.data = {})
          const directives = data?.directives || (data.directives = [])
          if (!directives.some(({ name }) => name === 'monitor')) {
            directives.push({ name: 'monitor', value: this.monitor })
          }

          if (this.monitorExtra) {
            const attrs = data?.attrs || (data.attrs = {})
            attrs['data-monitor-extra'] = JSON.stringify(this.monitorExtra)
          }
        }
      })
    }

    return slots as unknown as VNode
  },
}
