<template>
  <div class="container">
    <div class="modal-height">
      <div class="file-box">
        <p class="file-name" v-show="!renderLoading">{{ file.filename }}</p>
        <div class="view-wrapper">
          <div class="preview-wrapper" ref="wrapper" v-if="isAbleView">
            <div class="preview-inner" ref="preview-inner">
              <div class="preview-mark" ref="bg-mark" id="bg-mark"></div>
              <div class="output" v-show="!renderLoading" ref="output"></div>
              <div class="loading" v-if="renderLoading">
                <el-spinner>
                  <template #default>
                    <div class="spinner">
                      <div class="bounce1"></div>
                      <div class="bounce2"></div>
                      <div class="bounce3"></div>
                    </div>
                  </template>
                </el-spinner>
              </div>
            </div>
          </div>
          <view-other-component
            v-else-if="file.type && !isAbleView"
            :file="file"
          />
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import commJs from "@/comm_js"
import { render } from "@/components/view_file/util"
import ViewOtherComponent from "@/components/view_file/vendors/other/index"
export default {
  name: "ViewFileComponent",
  components: {
    ViewOtherComponent,
  },
  props: {
    file: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  data() {
    return {
      reFreshFlag: false,
      renderLoading: false,
    }
  },
  computed: {
    // 可在在线预览文件类型
    isAbleView() {
      const lowType = (this.file.type || "").toLowerCase()
      const typeObject = {
        doc: ["docx"],
        xlsx: ["xlsx"],
        pdf: ["pdf"],
        ppt: ["pptx"],
        image: ["gif", "jpg", "jpeg", "bmp", "tiff", "tif", "png", "svg"],
        text: [
          "txt",
          "json",
          "js",
          "css",
          "java",
          "py",
          "html",
          "jsx",
          "ts",
          "tsx",
          "xml",
          "md",
          "log",
        ],
      }
      const ablePreviewTypes = Object.values(typeObject).flat()
      return ablePreviewTypes.includes(lowType)
    },
  },
  methods: {
    /**
     * @{params} buffer 文件字节流
     * @{params} extend 文件扩展名
     */
    renderResult(buffer, extend) {
      const { output } = this.$refs
      output.innerHTML = ""
      const node = document.createElement("div")
      const child = output.appendChild(node)
      return new Promise((resolve, reject) =>
        render(buffer, extend, child).then(resolve).catch(reject)
      )
    },
  },
  watch: {
    file: {
      handler(newFile) {
        if (newFile && newFile.type) {
          try {
            this.renderLoading = true
            this.renderResult(newFile.fileBuffer, newFile.type).finally(() => {
              this.renderLoading = false
            })
          } catch (error) {
            console.warn(error)
          }
        }
      },
      immediate: true,
      deep: true,
    },
  },
}
</script>
<style lang="less">
.container {
  width: 100%;
  height: 100%;
  .docx-wrapper {
    background: unset !important;
    padding: 0 !important;

    & > section.docx {
      background: unset !important;
    }
  }
}
</style>
<style lang="less" scoped>
@import url("./index.less");
@deep: ~">>>";

@{deep} .header-rewrite {
  margin-bottom: 0 !important;
}

.modal-height {
  display: flex;
  justify-content: space-between;
  height: 100%;
  .file-box {
    flex: 1;
    padding: 15px 40px;
    overflow: scroll;
    text-align: center;

    .file-name {
      line-height: 36px;
      text-align: center;
      font-size: 16px;
      font-weight: 500;
    }

    .view-wrapper {
      position: relative;
      width: 100%;
      height: ~"calc(100% - 36px)";
      overflow: hidden;
      .preview-inner {
        position: relative;
        width: 100%;
        height: 100%;
        .loading {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          z-index: 999;
        }
      }
    }
  }
}
</style>
