<template>
  <div class="top-bar">
    <div class="play-bar">
      <ui-icon
        :type="play ? 'a-pause' : 'a-play'"
        ctrl
        @click="
          () => {
            play = !play;
            $emit('update:follow', play);
          }
        "
      />
    </div>
    <div class="scale-bar">
      <ui-icon
        type="reduce"
        class="icon"
        ctrl
        @click="scale = Math.max(0.5, scale - 0.5)"
      />
      <Slider
        class="slider"
        v-model:value="scale"
        :min="0.5"
        :max="8"
        :step="0.01"
        :tooltipOpen="false"
      />
      <ui-icon
        type="magnify"
        class="icon"
        ctrl
        @click="scale = Math.min(8, scale + 0.5)"
      />
    </div>
  </div>
  <div class="oper-bar" :class="{ disabled: play }">
    <Renderer v-model:scale="scale" ref="renderer">
      <v-group>
        <template v-if="am">
          <template v-for="prop in tlProps">
            <TimeLine
              v-if="am[prop.attr].length"
              :items="am[prop.attr]"
              :height="prop.height"
              :background="prop.background"
              :opacity="prop.opacity"
              :top="prop.top"
              :itemsRenderer="prop.component"
              @update="({ ndx, time }) => (am![prop.attr][ndx].time = time)"
              @add="
                  (item) => {
                    am![prop.attr].push({...item, id: onlyId()});
                    $emit('update:active', {
                      key: prop.attr,
                      ndx: am![prop.attr].length - 1,
                    });
                  }
                "
              @del="(ndx) => am![prop.attr].splice(ndx, 1)"
              :active="prop.attr === active?.key ? am[prop.attr][active.ndx] : undefined"
              @update:active="(active: any) => $emit('update:active', active && { key: prop.attr, ndx: am![prop.attr].indexOf(active) })"
            />
          </template>
          <empty v-if="!count" />
        </template>
      </v-group>
      <v-group>
        <Time
          @update-current-time="
            (time) => {
              $emit('update:currentTime', time);
            }
          "
        >
          <TimeCurrent
            :currentTime="currentTime"
            @update:current-time="(time) => $emit('update:currentTime', time)"
            :follow="follow"
          />
        </Time>
      </v-group>
    </Renderer>
  </div>
</template>

<script lang="ts" setup>
import { Slider } from "ant-design-vue";
import { computed, ref, watch, watchEffect } from "vue";
import { ams, AnimationModel } from "@/store/animation";
import Renderer from "@/components/drawing/renderer.vue";
import Time from "@/components/drawing-time/time.vue";
import TimeCurrent from "@/components/drawing-time/current.vue";
import TimeLine from "@/components/drawing-time-line/index.vue";
import TimeLineFrame from "@/components/drawing-time-line/frame.vue";
import TimeLineAction from "@/components/drawing-time-line/action.vue";
import empty from "@/components/drawing-time-line/empty.vue";
import { Active } from "./type";
import { animationGroup, currentTime, endTime } from "@/sdk/association/animation";
import { onlyId } from "@/components/drawing/hook";

const props = defineProps<{
  am?: AnimationModel;
  active?: Active;
  currentTime: number;
  follow: boolean;
}>();
const emit = defineEmits<{
  (e: "update:active", data: Active | undefined): void;
  (e: "update:follow", data: boolean): void;
  (e: "update:currentTime", v: number): void;
}>();

const scale = ref(1);

const tlProps = [
  {
    attr: "frames",
    component: TimeLineFrame,
    height: 30,
    top: 24,
    background: "#000",
    opacity: 0.5,
  },
  {
    attr: "actions",
    component: TimeLineAction,
    height: 30,
    top: 65,
    background: "#000",
    opacity: 0.5,
  },
  {
    attr: "subtitles",
    component: TimeLineAction,
    height: 30,
    top: 105,
    background: "#000",
    opacity: 0.5,
  },
  {
    attr: "paths",
    component: TimeLineAction,
    height: 30,
    top: 145,
    background: "#000",
    opacity: 0.5,
  },
] as const;

const count = computed(() =>
  Object.values(tlProps).reduce((t, c) => (props.am ? t + props.am[c.attr].length : 0), 0)
);

const play = ref(false);

watch(play, (_a, _b, onCleanup) => {
  play.value ? animationGroup.play() : animationGroup.pause();
  onCleanup(
    watchEffect(() => {
      if (currentTime.value >= endTime.value) {
        play.value = false;
      }
    })
  );

  // let isDes = false;
  // let prevNow = Date.now();
  // const animation = () => {
  //   if (play.value && !isDes) {
  //     const curNow = Date.now();
  //     emit("update:currentTime", props.currentTime + (curNow - prevNow) * 0.001);
  //     prevNow = curNow;
  //     requestAnimationFrame(animation);
  //   }
  // };
  // animation();
  // onCleanup(() => (isDes = true));
});

const renderer = ref<any>();
watch(
  () => props.am,
  () => renderer.value.updateSize()
);
</script>

<style scoped lang="scss">
.top-bar {
  display: flex;
  height: 40px;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
  .play-bar {
    flex: 1;
    display: flex;
    justify-content: center;
    .icon {
      font-size: 16px;
    }
  }
  .scale-bar {
    width: 180px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    padding: 0 20px;
    position: relative;
    &::before {
      content: "";
      position: absolute;
      left: 0;
      width: 1px;
      height: 16px;
      background: rgba(255, 255, 255, 0.16);
    }

    .slider {
      flex: 1;
    }
    .icon {
      margin: 0 5px;
      font-size: 16px;
    }
  }
}
.oper-bar {
  height: calc(100% - 40px);
}
</style>
