<template>
  <div
    class="history-view"
    @mousedown.passive="onMouseDown"
    @mousemove.passive="onMouseMove"
    @mouseup="onMouseUp"
    @mouseleave="onMouseLeave"
  >
    <video
      src="@/assets/videos/bg-history.mp4"
      class="bg"
      autoplay
      loop
    />
    <div
      class="gear-wrap"
      @click="doTest"
    >
      <img
        class="gear"
        :src="require(`@/assets/images/gear/表盘1_${gearFrameIdx.toString().padStart(5, '0')}.png`)"
        alt=""
        draggable="false"
      >
    </div>
    <div
      v-if="currentTimeIdx !== null"
      class="current-stage-name"
    >
      <h1>{{ stageList[currentTimeIdx].name }}</h1>
      <img
        class="underline"
        src="@/assets/images/underline-history-stage.png"
        alt=""
        draggable="false"
      >
    </div>
    <div
      class="time-axis-wrap"
      :style="{
        left: `${timeAxisLeft}px`,
      }"
    >
      <div
        v-for="index in timeAxisScaleRepeat"
        :key="index"
        class="scale-line"
        :style="{
          width: `${timeAxisScaleWidth}px`,
          marginRight: `${timeAxisScaleMargin}px`,
          opacity: computeTimeAxisScaleOpacity(index),
        }"
      />
      <div
        v-for="index in timeAxisScaleRepeat"
        :key="index"
        class="scale-line"
        :style="{
          width: `${timeAxisScaleWidth}px`,
          marginRight: `${timeAxisScaleMargin}px`,
          opacity: computeTimeAxisScaleOpacity(index + timeAxisScaleRepeat),
        }"
      />
    </div>
    <div
      v-for="stageLabel in stageLabelList"
      :key="stageLabel.name"
      class="stage-label"
      :style="{
        left: stageLabel.left + 'px',
      }"
    >
      {{ stageLabel.startTime }}
      <img
        draggable="false"
        src="@/assets/images/star.png"
        alt=""
        class="star animation-show-hide"
      >
    </div>
    <HistoryPersonCard
      v-for="(item) in personList"
      :key="item.id"
      class="history-person-card"
      :name="item.name"
      :img="item.img"
      :text="item.description || item.story"
      :tall-or-fat="item.tallOrFat"
      :style="{
        left: item.left + 'px',
        top: item.top + 'px',
        zIndex: item.zIndex,
        filter: item.filter,
      }"
    />
  </div>
</template>

<script>
import { reactive, toRefs, ref, watch, onMounted, onBeforeUnmount, computed } from 'vue'
import HistoryPersonCard from "@/components/HistoryPersonCard.vue"
import axios from "axios"

export default {
  components: {
    HistoryPersonCard,
  },
  setup () {
    const spaceEachPerson = 220

    // 时代阶段
    const stageList = reactive([
      {
        name: '开埠通商',
        startTime: '1843',
        endTime: '1894',
        startTimeFriendly: '19世纪40年代',
        endTimeFriendly: '19世纪90年代',
        components: '上海近代工业蹒跚起步',
      },
      {
        name: '曲折发展',
        startTime: '1895',
        endTime: '1936',
        startTimeFriendly: '19世纪90年代',
        endTimeFriendly: '20世纪30年代',
        components: '上海近代工业起起伏伏',
      },
      {
        name: '步履维艰',
        startTime: '1937',
        endTime: '1949',
        startTimeFriendly: '20世纪30年代',
        endTimeFriendly: '20世纪50年代',
        components: '上海民族工业几经崩溃',
      },
      {
        name: '筚路蓝缕',
        startTime: '1950',
        endTime: '1978',
        startTimeFriendly: '20世纪50年代',
        endTimeFriendly: '20世纪70年代',
        components: '上海现代工业扬帆起航',
      },
      {
        name: '改革开放',
        startTime: '1979',
        endTime: '1996',
        startTimeFriendly: '20世纪70年代',
        endTimeFriendly: '20世纪90年代',
        components: '上海工业凤凰涅槃',
      },
      {
        name: '战略负重',
        startTime: '1997',
        endTime: '2011',
        startTimeFriendly: '20世纪90年代',
        endTimeFriendly: '本世纪10年代',
        components: '上海工业筑梦前行',
      },
      {
        name: '创新驱动',
        startTime: '2012',
        endTime: '2020',
        startTimeFriendly: '本世纪10年代',
        endTimeFriendly: '本世纪20年代',
        components: '上海工业转型升级',
      },
      {
        name: '追梦未来',
        startTime: '2021',
        endTime: '2035',
        startTimeFriendly: '本世纪20年代',
        endTimeFriendly: '本世纪30年代',
        components: '上海工业再创辉煌',
      },
    ])

    // 获取数据
    Promise.allSettled(stageList.map((stageItem) => {
      return axios({
        method: 'post',
        url: `https://sit-shgybwg.4dage.com/api/show/history/pageList`,
        headers: {
          "Content-Type": "application/json",
        },
        data: {
          stage: stageItem.name
        },
      }).then((res) => {
        return res.data.data.records
      }).then((res) => {
        stageItem.personList = res
        const personWidth = spaceEachPerson
        stageItem.width = personWidth * res.length
      }).then(() => {
        // 获取各人物的照片
        for (const personItem of stageItem.personList) {
          api.getHistoryDetail(personItem.id).then((res) => {
            try {
              personItem.img = process.env.VUE_APP_API_ORIGIN + res.file[0].filePath
            } catch (e) {
              console.log(e)
            }
          })
        }
      })
    })).then((res) => {
      // 计算各个时代的起始终止位置
      let temp = 0
      for (const stageItem of stageList) {
        stageItem.startPos = temp
        stageItem.endPos = temp + stageItem.width
        temp = stageItem.endPos
      }
      maxTranslateLength.value = stageList[stageList.length - 1].endPos
    })

    // 用户操作相关
    const isMouseDown = ref(false)
    const lastMoveEventTimeStamp = ref(0)
    const lastCursorPos = ref(0)

    // 镜头平移相关
    const moveSpeed = ref(0)
    const translateLength = ref(0)
    const maxTranslateLength = ref(0)

    // 用户操作改变镜头平移速度
    function onMouseDown(e) {
      isMouseDown.value = true
      moveSpeed.value = 0
      lastMoveEventTimeStamp.value = 0
      lastAnimationTimeStamp = Date.now()
      lastCursorPos.value = e.clientX
      if (beginAutoMoveIntervalId) {
        clearInterval(beginAutoMoveIntervalId)
        beginAutoMoveIntervalId = null
      }
      if (isAutoMoving.value) {
        isAutoMoving.value = false
      }
    }
    function onMouseUp(e) {
      isMouseDown.value = false
      beginAutoMoveIntervalId = setInterval(() => {
        if (moveSpeed.value === 0) {
          isAutoMoving.value = true
        }
      }, 2000)
    }
    function onMouseLeave() {
      isMouseDown.value = false
    }
    function onMouseMove(e) {
      if (isMouseDown.value) {
        // 疯狂操作的极端情况下两个时间戳之间的时差会不合理，甚至为0
        if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
          // 更新speed
          const currentMoveSpeed = - (e.clientX - lastCursorPos.value) / (e.timeStamp - lastMoveEventTimeStamp.value) * 1
          moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
          lastCursorPos.value = e.clientX
        }
        lastMoveEventTimeStamp.value = e.timeStamp
      }
    }

    /**
     * 镜头自动平移
     */
    let isAutoMoving = ref(false)
    let beginAutoMoveIntervalId = null
    watch(isAutoMoving, (vNew) => {
      if (vNew) {
        moveSpeed.value = 0.03
      } else {
        moveSpeed.value = 0
      }
    })
    onBeforeUnmount(() => {
      clearInterval(beginAutoMoveIntervalId)
    })

    /**
     * 动画帧相关
     */
    let lastAnimationTimeStamp = 0
    let animationFrameId = null
    // 在每一帧更新镜头速度、位置
    function animationFrameTask() {
      const timeStamp = Date.now()
      const timeElapsed = timeStamp - lastAnimationTimeStamp
      if (!isAutoMoving.value) {
        // 速度减慢
        if (moveSpeed.value > 0) {
          moveSpeed.value -= ($.valueisMobile ? 0.001 : 0.003) * timeElapsed
          if (moveSpeed.value < 0) {
            moveSpeed.value = 0
          }
        } else if (moveSpeed.value < 0) {
          moveSpeed.value += ($.valueisMobile ? 0.001 : 0.003) * timeElapsed
          if (moveSpeed.value > 0) {
            moveSpeed.value = 0
          }
        }
      }

      // 根据速度更新位置
      translateLength.value += moveSpeed.value * timeElapsed
      if (translateLength.value < 0) {
        translateLength.value = 0
        moveSpeed.value = 0
      } else if (translateLength.value > maxTranslateLength.value) {
        if (isAutoMoving.value) {
          translateLength.value = 0
        } else {
          translateLength.value = maxTranslateLength.value
          moveSpeed.value = 0
        }
      }
      lastAnimationTimeStamp = timeStamp
      animationFrameId = requestAnimationFrame(animationFrameTask)
    }
    onMounted(() => {
      animationFrameId = requestAnimationFrame(animationFrameTask)
    })
    onBeforeUnmount(() => {
      cancelAnimationFrame(animationFrameId)
    })

    // 动画
    // 恢复历史位置
    // if (this.longImageTranslateLengthRecord) {
    //   this.translateLength = this.longImageTranslateLengthRecord
    //   this.setLongImageTranslateLengthRecord(null)
    // }

    /**
     * 当前时代相关
     */
    const currentTimeIdx = ref(0)
    watch(translateLength, (vNew) => {
      for (let index = 0; index < stageList.length; index++) {
        const stageItem = stageList[index]
        if (vNew >= (stageItem.startPos - window.innerWidth / 7) && vNew <= (stageItem.endPos - window.innerWidth / 7)) {
          currentTimeIdx.value = index
          break
        } else {
          currentTimeIdx.value = null
        }
      }
    })

    // 时间轴
    const timeAxisLeft = ref(0)
    const timeAxisScaleWidth = 2
    const timeAxisScaleMargin = 120
    const timeAxisScaleRepeat = 20
    watch(translateLength, (vNew) => {
      timeAxisLeft.value = -(vNew % ((timeAxisScaleWidth + timeAxisScaleMargin) * timeAxisScaleRepeat))
    })
    const windowCenterX = window.innerWidth / 2
    function computeTimeAxisScaleOpacity(index) { // 注意index是从1开始的
      const scaleCenterXInWindow = (timeAxisScaleWidth + timeAxisScaleMargin) * (index - 1) + timeAxisScaleWidth / 2 + timeAxisLeft.value
      return String(Math.max(1 - Math.abs(windowCenterX - scaleCenterXInWindow) / (windowCenterX), 0))
    }

    // 齿轮
    const gearFrameNumberTotal = 24
    const gearFrameIdx = ref(0)
    const gearFrameNumberPerScale = 3
    const translateLengthPerGrearFrame = (timeAxisScaleWidth + timeAxisScaleMargin) / gearFrameNumberPerScale
    watch(translateLength, (vNew) => {
      const framePassed = Math.round(translateLength.value / translateLengthPerGrearFrame)
      if (framePassed >= 0) {
        gearFrameIdx.value = framePassed % gearFrameNumberTotal
      } else {
        gearFrameIdx.value = gearFrameNumberTotal + framePassed % gearFrameNumberTotal - 1
      }
    })

    // 各个时代标签
    const stageLabelList = computed(() => {
      return stageList.map((item) => {
        if (item?.personList?.length) {
          return {
            name: item.name,
            initialLeft: (item.startPos + 10) * 3,
            left: (item.startPos + 10) * 3,
            startTime: item.startTime + '年',
          }
        } else {
          return undefined
        }
      }).filter((item) => {
        return !!item
      })
    })
    watch(translateLength, (vNew) => {
      for (const iterator of stageLabelList.value) {
        iterator.left = iterator.initialLeft - vNew * 3
      }
    })

    // 各个人物
    const personList = computed(() => {
      const ret = []
      stageList.map((stageItem) => {
        if (stageItem.personList) {
          for (const personItem of stageItem.personList) {
            const tallOrFat = (ret.length % 2 === 0 ? 'tall' : 'fat')
            ret.push({
              ...personItem,
              initialLeft: (ret.length * spaceEachPerson + spaceEachPerson / (tallOrFat === 'tall' ? 2 : 1.3)) * (tallOrFat === 'tall' ? 2 : 1.5),
              left: (ret.length * spaceEachPerson + spaceEachPerson / (tallOrFat === 'tall' ? 2 : 1.3)) * (tallOrFat === 'tall' ? 2 : 1.5),
              top: Math.random() * 70 + (tallOrFat === 'tall' ? 250 : 350),
              tallOrFat,
              zIndex: tallOrFat === 'tall' ? 5 : 4,
              filter: `brightness(${tallOrFat === 'tall' ? '1' : '0.75'})`,
            })
          }
        }
      })
      return ret
    })
    watch(translateLength, (vNew) => {
      for (const iterator of personList.value) {
        iterator.left = iterator.initialLeft - vNew * (iterator.tallOrFat === 'tall' ? 2 : 1.5)
      }
    })


    return {
      onMouseDown,
      onMouseMove,
      onMouseUp,
      onMouseLeave,
      timeAxisLeft,
      timeAxisScaleWidth,
      timeAxisScaleMargin,
      timeAxisScaleRepeat,
      computeTimeAxisScaleOpacity,
      gearFrameIdx,
      stageList,
      currentTimeIdx,
      stageLabelList,
      personList,
    }
  }
}
</script>

<style lang="less" scoped>
.history-view {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  user-select: none;
  >video.bg{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  >.gear-wrap {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: calc(100vw * 940 / 1920);
    >img.gear{
      width: 100%;
    }
  }
  >.current-stage-name {
    position: absolute;
    left: 50%;
    top: 10.5vw;
    transform: translateX(-50%);
    width: 250px;
    text-align: center;
    >h1{
      font-size: 36px;
      font-family: Source Han Sans CN-Bold, Source Han Sans CN;
      font-weight: bold;
      color: #FFFFFF;
      line-height: 42px;
    }
    >img.underline{
      margin-top: -20px;
      width: 100%;
    }
  }
  >.time-axis-wrap{
    bottom: 32.4%;
    position: absolute;
    display: flex;
    >.scale-line{
      height: 30px;
      background-color: #91886b;
    }
  }
  >.stage-label{
    position: absolute;
    bottom: 15.7%;
    font-size: 96px;
    font-family: Source Han Sans CN-Bold, Source Han Sans CN;
    font-weight: bold;
    color: #FFFFFF;
    line-height: 97px;
    text-shadow: 10px 0px 0 black;
    z-index: 10;
    width: 407px;
    text-align: left;
    >img.star{
      position: absolute;
      left: 0;
      top: 0;
      transform: translate(-50%, -80%);
    }
  }
  >.history-person-card{
    position: absolute;
  }
}
</style>