<template>
  <div class="video">
    <div class="overflow">
      <ui-icon 
        ctrl 
        :type="isScenePlayIng ? 'pause' : 'preview'" 
        :disabled="!paths.length" 
        @click="play"
      />
      <ui-button 
        type="primary" 
        @click="addPath" 
        width="200px" 
        :class="{ disabled: isScenePlayIng }"
      >
        添加视角
      </ui-button>
    </div>
    <div class="info" v-if="paths.length">
      <div class="meta">
        <div class="length">
          <span>视频时长</span>{{paths.reduce((t, c) => t + c.time, 0).toFixed(1)}}s
        </div>
        <div 
          class="fun-ctrl clear" 
          @click="deleteAll" 
          :class="{ disabled: isScenePlayIng }"
        >
          <ui-icon type="del" />
          <span>清空画面</span>
        </div>
      </div>

      <div class="photo-list" ref="listVm">
        <template v-for="(path, i) in paths" :key="path.id">
          <div 
            class="photo" 
            :class="{ active: current === path, disabled: isScenePlayIng }"
            @click="changeCurrent(path)"
          >
            <ui-icon 
              type="del" 
              ctrl 
              @click.stop="deletePath(path)" 
              :class="{ disabled: isScenePlayIng }" 
            />
            <img :src="getResource(getFileUrl(path.cover))" />
          </div>
          <div class="set-phone-attr" v-if="i !== paths.length - 1">
            <ui-input 
              type="number" 
              width="54px" 
              height="26px"
              :modelValue="path.speed" 
              @update:modelValue="(val: number) => updatePathInfo(i, { speed: val })"
              :ctrl="false" 
              :min="0.1" 
              :max="10"
            >
              <template #icon><span>m/s</span></template>
            </ui-input>
            <ui-input 
              type="number" 
              width="54px" 
              height="26px" 
              :modelValue="path.time" 
              @update:modelValue="(val: number) => updatePathInfo(i, { time: val })"
              :ctrl="false" 
              :min="0.1" 
              :max="20" 
              class="time"
            >
              <template #icon><span class="time">s</span></template>
            </ui-input>
          </div>
        </template>
        
      </div>
    </div>
    <p class="un-video" v-else>暂无导览</p>
  </div>
</template>

<script setup lang="ts">
import { loadPack, togetherCallback, getFileUrl, asyncTimeout } from '@/utils'
import { sdk, playSceneGuide, pauseSceneGuide, isScenePlayIng } from '@/sdk'
import { createGuidePath, isTemploraryID, useAutoSetMode, guides, getGuidePaths, guidePaths } from '@/store'
import { Dialog, Message } from 'bill/index'
import { useViewStack } from '@/hook'
import { nextTick, ref, toRaw, watchEffect } from 'vue'
import { showRightPanoStack, showLeftCtrlPanoStack, showLeftPanoStack, showRightCtrlPanoStack, getResource } from '@/env'

import type { Guide, GuidePaths, GuidePath } from '@/store'
import type { CalcPathProps } from '@/sdk'

const props = defineProps< { data: Guide }>()
const paths = ref<GuidePaths>(getGuidePaths(props.data))
const current = ref<GuidePath>(paths.value[0])

const updatePathInfo = (index: number, calcInfo: CalcPathProps[1]) => {
  const info = sdk.calcPathInfo(
    paths.value.slice(index, index + 2) as any,
    calcInfo
  )
  Object.assign(paths.value[index], info)
}

useViewStack(() => 
  togetherCallback([
    showRightPanoStack.push(ref(false)),
    showLeftCtrlPanoStack.push(ref(false)),
    showLeftPanoStack.push(ref(false)),
    showRightCtrlPanoStack.push(ref(false)),
  ])
);

useAutoSetMode(paths, {
  save() {
    if (!paths.value.length) {
      Dialog.alert('无法保存空路径导览！')
      throw '无法保存空路径导览！'
    }
    const oldPaths = getGuidePaths(props.data)
    props.data.cover = paths.value[0].cover
    guidePaths.value = guidePaths.value
      .filter(path => !oldPaths.includes(path))
      .concat(paths.value)
    if (isTemploraryID(props.data.id)) {
      console.error("现在才保存？")
      guides.value.push(props.data)
    }
  },
}, false)

const addPath = () => {
  loadPack(async () => {
    const dataURL = await sdk.screenshot(260, 160)
    const res = await fetch(dataURL)
    const blob = await res.blob()

    const pose = sdk.getPose()
    const index = paths.value.indexOf(current.value) + 1
    const path: GuidePath = createGuidePath({ 
      ...pose, 
      guideId: props.data.id,
      cover: { url: dataURL, blob } 
    })
    paths.value.splice(index, 0, path)
    current.value = path
    if (paths.value.length > 1) {
      const index = paths.value.length - 2
      updatePathInfo(index, { time: 3 })
    }
  })
}

const deletePath = async (path: GuidePath, fore: boolean = false) => {
  if (fore || (await Dialog.confirm('确定要删除此画面吗？'))) {
    const index = paths.value.indexOf(path)
    if (~index) {
      paths.value.splice(index, 1)
    }
    if (path === current.value) {
      current.value = paths.value[index + (index === 0 ? 0 : -1)]
    }
  }
}

const deleteAll = async () => {
  if (await Dialog.confirm('确定要清空画面吗？')) {
    paths.value.length = 0
    current.value = paths.value[0]
  }
}

const changeCurrent = (path: GuidePath) => {
  sdk.comeTo({ dur: 300, ...path })
  current.value = path
}

const play = async () => {
  if (isScenePlayIng.value) {
    pauseSceneGuide()
  } else {
    changeCurrent(paths.value[0])
    await asyncTimeout(400)
    playSceneGuide(toRaw(paths.value), (index) => {
      current.value = paths.value[index - 1]
    })
  }
}

const listVm = ref<HTMLDivElement>()
watchEffect(async () => {
  const index = paths.value.indexOf(current.value)
  if (~index && listVm.value) {
    await nextTick()
    const scrollWidth = listVm.value.scrollWidth / paths.value.length
    const centerWidth = listVm.value.offsetWidth / 2
    const offsetLeft = scrollWidth * index - centerWidth

    listVm.value.scroll({
      left: offsetLeft,
      top: 0,
    })
  }
})
</script>

<style lang="scss" scoped>
.video {
  position: relative;

  .overflow {
    position: absolute;
    left: 50%;
    bottom: 100%;
    transform: translateX(-50%);
    margin-bottom: 20px;
    display: flex;
    align-items: center;

    .icon {
      margin-right: 20px;
      color: #fff;
      font-size: 30px;
    }
  }

  .meta {
    font-size: 12px;
    border-bottom: 1px solid rgba(255,255,255,.16);
    padding: 10px 20px;
    display: flex;
    justify-content: space-between;
    
    .length span {
      margin-right: 10px;
    }

    .clear {
      display: flex;
      align-items: center;
      .icon {
        font-size: 1.4em;
        margin-right: 5px;
      }
    }
  }


  .photo-list {
    padding: 10px 20px 20px;
    overflow-x: auto;
    display: flex;

    .set-phone-attr {
      padding: 0 10px;
      display: flex;
      flex-direction: column;
      justify-content: space-evenly;
      align-items: center;
      position: relative;

      &::before,
      &::after {
        content: '';
        color: rgba(255,255,255,.6);
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
      }
      &::before {
        left: 0;
        right: 7px;
        height: 2px;
        background-color: currentColor;
      }
      &::after {
        right: -5px;
        width: 0;
        height: 0;
        border: 5px solid transparent;
        border-left: 7px solid currentColor;
      }
    }
    
    .photo {
      cursor: pointer;
      flex: none;
      position: relative;
      

      &.active {
        outline: 2px solid var(--colors-primary-base);
      }

      .icon {
        position: absolute;
        right: 10px;
        top: 10px;
        width: 24px;
        font-size: 12px;
        height: 24px;
        background-color: rgba(0,0,0,0.6);
        color: rgba(255,255,255,.6);
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        border-radius: 50%;
      }


      img {
        width: 230px;
        height: 160px;
        display: block;
      }
    }
  }
}
.un-video {
  height: 100px;
  line-height: 100px;
  text-align: center;
  color: rgba(255,255,255,0.6);
  font-size: 1.2em;
}
</style>

<style lang="scss">
.set-phone-attr {
  .ui-input .text input {
    padding: 8px 4px;
  }
  .ui-input .text {
    font-size: 12px;
  }
  .ui-input .text.suffix .retouch {
    right: 4px;
  }
  .ui-input .text.suffix input {
    padding-right: 28px;
    text-align: right;
  }
  .ui-input.time .text.suffix input {
    padding-right: 18px;
    text-align: right;
  }
}
</style>