<template>
  <ui-group-option class="sign-guide">
    <div class="info">
      <div class="guide-cover">
        <img :src="getResource(getFileUrl(guide.cover))" />
        <ui-icon
          type="preview"
          class="icon"
          ctrl
          @click="playSceneGuide(paths, undefined, true)"
          v-if="paths.length"
        />
      </div>
      <div>
        <p>{{ guide.title }}</p>
      </div>
    </div>
    <div class="actions" v-if="edit">
      <ui-more
        :options="menus"
        style="margin-left: 20px"
        @click="(action: keyof typeof actions) => actions[action]()"
      />
    </div>
  </ui-group-option>
  <Teleport to="body">
    <div class="edit-add-type" v-if="downloading">
      <div class="edit-hot-item">
        <h3 class="edit-title">设置视频参数</h3>
        <ui-input
          require
          class="input"
          :options="[
            { value: '1080p', label: '1080p' },
            { value: '2k', label: '2k' },
            { value: '4k', label: '4k' },
          ]"
          width="100%"
          placeholder="设置分辨率"
          type="select"
          v-model="videoConfig.resolution"
          maxlength="15"
        />
        <ui-input
          require
          class="input"
          :options="[
            { value: 30, label: '30' },
            { value: 60, label: '60' },
            { value: 90, label: '90' },
          ]"
          width="100%"
          placeholder="设置帧率"
          type="select"
          v-model="videoConfig.frameRate"
          maxlength="15"
        />
        <div>
          <span>预计渲染时间：</span>
          <span>{{ time }}s</span>
        </div>
        <div class="edit-hot">
          <a @click="() => (downloading = false)">
            <ui-icon type="nav-edit" />
            确定
          </a>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { Guide, getGuidePaths } from "@/store";
import { getFileUrl, saveAs } from "@/utils";
import { getResource } from "@/env";
import { computed, watchEffect, nextTick, ref } from "vue";
import { playSceneGuide, isScenePlayIng, pauseSceneGuide } from "@/sdk";
import { VideoRecorder } from "@simaq/core";

const props = withDefaults(defineProps<{ guide: Guide; edit?: boolean }>(), {
  edit: true,
});

const emit = defineEmits<{
  (e: "delete"): void;
  (e: "play"): void;
  (e: "edit"): void;
}>();

const menus = [
  { label: "编辑", value: "edit" },
  { label: "下载", value: "download" },
  { label: "删除", value: "delete" },
];
const downloading = ref(false);
const videoConfig = ref({
  resolution: "1080p",
  frameRate: 60,
});

const actions = {
  edit: () => emit("edit"),
  delete: () => emit("delete"),
  download: async () => {
    downloading.value = true;
    await new Promise<void>((resolve) => {
      const stop = watchEffect(() => {
        if (downloading.value === false) {
          stop();
          resolve();
        }
      });
    });
    const config: any = {
      // uploadUrl: '',
      // resolution: '1080p' | '2k' | '4k';
      // frameRate： [30, 60, 90]
      // autoDownload: false,
      // systemAudio: true,
      // debug: true,
      resolution: videoConfig.value.resolution || "1080p",
      autoDownload: false,
      platform: "canvas",

      config: {
        frameRate: videoConfig.value.frameRate || 60,
        canvasId: ".scene-canvas > canvas",
      },
      disbaledAudio: false,
      systemAudio: false,
      debug: false,
    };

    const videoRecorder = new VideoRecorder(config);
    videoRecorder.startRecord();

    let stopWatch: () => void;
    const stopRecord = () => {
      stopWatch && stopWatch();
      pauseSceneGuide();
    };

    videoRecorder.on("record", (blob) => {
      saveAs(
        new File([blob], "录屏.mp4", { type: "video/mp4; codecs=h264" }),
        props.guide.title + ".mp4"
      );
    });

    videoRecorder.off("*");
    videoRecorder.on("startRecord", () => {
      playSceneGuide(paths.value, undefined, true);
      stopWatch = watchEffect(() => {
        if (!isScenePlayIng.value) {
          videoRecorder.endRecord();
          nextTick(stopWatch);
        }
      });
    });
    videoRecorder.on("cancelRecord", stopRecord);
    videoRecorder.on("endRecord", stopRecord);
  },
};
const paths = computed(() => getGuidePaths(props.guide));
const time = computed(() => paths.value.reduceRight((t, c) => t + c.time, 0));
</script>

<style lang="scss" scoped>
.sign-guide {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 0;
  border-bottom: 1px solid var(--colors-border-color);
  &:first-child {
    border-top: 1px solid var(--colors-border-color);
  }

  .info {
    flex: 1;

    display: flex;
    align-items: center;

    .guide-cover {
      position: relative;
      &::after {
        content: "";
        position: absolute;
        inset: 0;
        background: rgba(0, 0, 0, 0.2);
      }

      .icon {
        position: absolute;
        z-index: 1;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        font-size: 16px;
      }

      img {
        width: 48px;
        height: 48px;
        object-fit: cover;
        border-radius: 4px;
        overflow: hidden;
        background-color: rgba(255, 255, 255, 0.6);
        display: block;
      }
    }

    div {
      margin-left: 10px;

      p {
        color: #fff;
        font-size: 14px;
        margin-bottom: 6px;
      }
    }
  }

  .actions {
    flex: none;
  }
}

.edit-add-type {
  color: #fff;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
  z-index: 2000;
  padding: 20px;
  overflow-y: auto;

  .edit-hot-item {
    margin: 100px auto 20px;
    width: 400px;
    padding: 20px;
    background: rgba(27, 27, 28, 0.8);
    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
    border-radius: 4px;

    .input {
      margin-bottom: 10px;
    }
  }
}

.edit-hot {
  margin-top: 20px;
  text-align: right;

  span {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.6);
    cursor: pointer;
  }
}

.edit-close {
  position: absolute;
  cursor: pointer;
  top: calc((100% - 18px) / 2);
  right: 0;
  transform: translateY(-50%);
}

.edit-title {
  padding-bottom: 18px;
  margin-bottom: 18px;
  position: relative;
  color: #fff;

  &::after {
    content: "";
    position: absolute;
    left: -20px;
    right: -20px;
    height: 1px;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.16);
  }
}

.edit-title {
  padding-bottom: 18px;
  margin-bottom: 18px;
  position: relative;

  &::after {
    content: "";
    position: absolute;
    left: -20px;
    right: -20px;
    height: 1px;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.16);
  }
}
</style>
