<template>
  <teleport :to="appEl" v-if="appEl">
    <!-- <div class="countdown strengthen" v-if="!custom.showBottomBar && countdown">
      <p class="title"><span>{{countdown}}</span>秒后开始录制</p>
      <p>按ESC可暂停录制</p>
    </div> -->

    <ui-editor-toolbar :toolbar="custom.showBottomBar" class="shot-ctrl">
      <ui-button type="submit" class="btn" @click="close">取消</ui-button>
      <ui-button type="primary" class="btn" @click="complete" :class="{disabled: blobs.length === 0}">合并视频</ui-button>
      <div class="other" :style="{bottom: barHeight}">
        <ui-icon class="icon" type="video1" ctrl @click="start" tip="继续录制" tipV="top" />
      </div>
      <div class="video-list" v-if="videoList.length">
        <div class="layout" :style="{width: `${videoList.length * 130}px`}">
          <div v-for="video in videoList" :key="video.cover" class="cover">
            <img :src="video.cover">
            <ui-icon 
              type="preview" 
              ctrl 
              class="preview" 
              @click="palyUrl = video.origin"  
            />
          </div>
        </div>
      </div>
    </ui-editor-toolbar>

    <Preview 
      v-if="palyUrl" 
      :items="[{ type: MediaType.video, url: palyUrl }]"
      @close="palyUrl = null" 
    />

    <ShotImiate v-if="!custom.showBottomBar && !countdown" />
  </teleport>
</template>

<script lang="ts">
import { ref, defineComponent, onUnmounted, watch, shallowReactive, PropType, computed, watchEffect } from 'vue'
import { VideoRecorder } from '@simaq/core';
import { sdk } from '@/sdk'
import { getVideoCover, togetherCallback } from '@/utils'
import { MediaType, Preview } from '@/components/static-preview/index.vue'
import { Record, getRecordFragmentBlobs } from '@/store'
import ShotImiate from './shot-imitate.vue'
import { 
  getResource, 
  showRightCtrlPanoStack, 
  showRightPanoStack, 
  showBottomBarStack, 
  custom, 
  bottomBarHeightStack,
  showHeadBarStack,
  showLeftPanoStack
} from '@/env'
import { appEl } from '@/store';
import { useViewStack } from '@/hook';
import { currentModel } from '@/model';
import { Message } from 'bill/expose-common';


export default defineComponent({
  props: {
    record: {
      type: Object as PropType<Record>,
      required: true
    }
  },
  emits: {
    'append': (blobs: Blob[]) => true,
    'updateCover': (cover: string) => true,
    'close': () => true,
    'preview': () => true,
    'deleteRecord': () => true
  },
  setup(props, { emit }) {
    const config: any = {
      uploadUrl: '',
      resolution: '4k',
      debug: false,
    }
  
    const videoRecorder = new VideoRecorder(config);
    const showLeftPano = ref(false)
    const showBottomBar = ref(false)
    const MAX_SIZE = 2 * 1024 * 1024 * 1024
    const MAX_TIME = 30 * 60 * 1000

    type VideoItem = { origin: Blob | string, cover: string }

    const countdown = ref(0)
    let interval: NodeJS.Timer
    let recordIng = ref(false)
    const start = () => {
      if (size.value > MAX_SIZE || pauseTime.value < 2000) {
        return Message.warning('已超出限制大小无法继续录制，可保存后继续录制！')
      }

      showBottomBar.value = false
      countdown.value = 2
      const timeiffe = () => {
        if (--countdown.value <= 0) {
          clearInterval(interval)
          videoRecorder.startRecord()
          recordIng.value = true
        } else {
          interval = setTimeout(timeiffe, 300)
        }
      }
      timeiffe()
      // interval = setInterval(() => {
      //   if (--countdown.value === 0) {
      //     clearInterval(interval)
      //     videoRecorder.startRecord()
      //     recordIng = true
      //   }
      // }, 1000)
    }

    const pause = () => {
      if (countdown.value === 0 && recordIng.value) {
        videoRecorder.endRecord()
        recordIng.value = false
      }
      countdown.value = 0
      showBottomBar.value = true
      clearInterval(interval)
    }

    watch(recordIng, (_n, _o, onCleanup) => {
      if (recordIng.value) {
        const timeout = setTimeout(() => videoRecorder.endRecord(), pauseTime.value)
        onCleanup(() => clearTimeout(timeout))
      }
    })

    const blobs: File[] = shallowReactive([])
    const size = computed(() => {
      console.log(videoList)
      return videoList.reduce((t, f) => typeof f.origin === 'string' ? t : t + f.origin.size, 0)
    })
    const pauseTime = computed(() => (MAX_TIME / MAX_SIZE) * (MAX_SIZE - size.value))
    videoRecorder.off('*')
    videoRecorder.on('record', blob => {
      if (recordIng.value) {
        blobs.push(new File([blob], '录屏.mp4', { type: 'video/mp4; codecs=h264' }))
      }
    })
    videoRecorder.on('cancelRecord', pause)
    videoRecorder.on('endRecord', pause)

    const palyUrl = ref<string | Blob | null>(null)
    const videoList: VideoItem[] = shallowReactive([])
    let initial = false
    watch([blobs, props], async () => {
      const existsVideos = []

      if (props.record.url) {
        existsVideos.push(getResource(props.record.url))
      }
      const fragmentBlobs = getRecordFragmentBlobs(props.record)
      existsVideos.push(...fragmentBlobs, ...blobs)
      for (const blob of existsVideos) {
        if (videoList.some(item => item.origin === blob)) {
          continue
        }
        const cover = await getVideoCover(blob, 3, 120, 80)
        videoList.push({ origin: blob, cover })
      }
      for (let i = 0; i < videoList.length; i++) {
        if (!existsVideos.some(blob => videoList[i].origin === blob)) {
          videoList.splice(i--, 1)
        }
      }
      if (!props.record.cover && videoList.length) {
        emit('updateCover', videoList[0].cover)
      }
      if (!initial) {
        initial = true
        start()
      }
      
    }, { immediate: true })

    const upHandler = (ev: KeyboardEvent) => ev.code === `Escape` && videoRecorder.endRecord()
    document.body.addEventListener('keyup', upHandler, { capture: true })

    const complete = () => {
      emit('append', blobs)
      close()
    }

    const close = () => {
      pause()
      emit('close')
    }

    const barHeight = computed(() => videoList.length ? '180px' : '60px')
    
    onUnmounted(() => {
      document.body.removeEventListener('keyup', upHandler, { capture: true })
    })


    watch(currentModel, () => {
      if (currentModel.value) {
        showLeftPano.value = false
      }
    })
    useViewStack(() => {
      return togetherCallback([
        showHeadBarStack.push(ref(false)),
        showRightCtrlPanoStack.push(ref(false)),
        showRightPanoStack.push(ref(false)),
        showBottomBarStack.push(showBottomBar),
        bottomBarHeightStack.push(barHeight),
        showLeftPanoStack.push(showLeftPano),
        close,
        () => {
          console.log('pop', showBottomBarStack.current)
        }
      ])
    })

    return {
      MediaType,
      complete,
      pause,
      close,
      start,
      barHeight,
      el: sdk.layout,
      blobs,
      countdown,
      custom,
      videoList,
      palyUrl,
      appEl
    }
  },
  components: {
    Preview,
    ShotImiate
  }
})

</script>

<style lang="scss" src="./style.scss" scoped>
</style>