<template>
  <div class="w-full h-full overflow-hidden flex flex-col">
    <ViewTitle title="Schema" />
    <div class="w-full flex-1 overflow-hidden">
      <MonacoEditor
        ref="editorRef"
        value-format="json"
        :config="{ minimap: { enabled: true } }"
        :allow-fullscreen="false"
        read-only
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, ref, watch } from 'vue'
import MonacoEditor from '@/components/MonacoEditor/index.vue'
import { useProjectStore } from '@/store/modules/project'
import ViewTitle from '@/components/ViewTitle/index.vue'

const projectStore = useProjectStore()
const editorRef = ref<InstanceType<typeof MonacoEditor>>()
type IdleWindow = Window & {
  requestIdleCallback?: (callback: IdleRequestCallback, options?: IdleRequestOptions) => number
  cancelIdleCallback?: (handle: number) => void
}

let updateTimer: ReturnType<typeof setTimeout> | undefined
let idleId: number | undefined

const clearScheduledUpdate = () => {
  if (updateTimer !== undefined) {
    clearTimeout(updateTimer)
    updateTimer = undefined
  }

  if (idleId !== undefined) {
    ;(window as IdleWindow).cancelIdleCallback?.(idleId)
    idleId = undefined
  }
}

const updateEditor = () => {
  editorRef.value?.setValue(JSON.stringify(projectStore.project, null, 2))
}

const scheduleUpdate = () => {
  clearScheduledUpdate()
  updateTimer = setTimeout(() => {
    updateTimer = undefined
    const idleWindow = window as IdleWindow

    if (idleWindow.requestIdleCallback) {
      idleId = idleWindow.requestIdleCallback(
        () => {
          idleId = undefined
          updateEditor()
        },
        { timeout: 1000 }
      )
      return
    }

    updateEditor()
  }, 300)
}

watch(
  () => projectStore.projectRevision,
  () => {
    scheduleUpdate()
  },
  {
    immediate: true
  }
)

onBeforeUnmount(() => {
  clearScheduledUpdate()
})
</script>

<style scoped></style>
