<template>
  <RenderFile />
</template>

<script setup lang="tsx" name="LjFilePreview_PreviewFile">
import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { GetCacheFile } from "@/api/modules/common";
import LjDialog from "@/components/LjDialog/index.vue";
import type { FileData } from "@/typings/business";
import { isArray } from "@/utils/is";
import VueOfficeDocx from "@vue-office/docx";
import VueOfficeExcel from "@vue-office/excel";
import VueOfficePdf from "@vue-office/pdf";
import { getBase64Type } from "@/utils/index";
import { onBeforeUnmount } from "vue";
import { ArrowLeft, ArrowRight, Close, Document } from "@element-plus/icons-vue";

interface LjFileProps {
  /**
   * @description 抽屉基础属性
   */
  drawerProp?: any;
  /**
   * @description 文件数据
   */
  files: FileData[];
  /**
   * @description 初始预览图像索引，小于 url-list 的长度
   */
  initialIndex?: number;
  closed?: () => void;
  updated: (data: any, index: number) => any;
}

// interface FileParams {
//   /**
//    * @description 附件类型id
//    */
//   billtype: number;
//   classid?: number;
//   relid?: number;
//   relidmx?: number;
//   scid?: number | undefined;
//   relcode?: string | undefined;
// }

const props = withDefaults(defineProps<LjFileProps>(), {
  drawerProp: {
    width: "80%",
    "destroy-on-close": true,
    "append-to-body": true,
    modalClass: "lj-file-views-dialog"
  },
  files: () => []
});
const emit = defineEmits(["update"]);

/**
 * @description 抽屉默认属性
 */
const drawerDefineProp = {
  draggable: true,
  overflow: true
};

const LjDialogFileRef = ref();
const fileData = ref();
const isSrcList = ref<any>([]);
const VueOfficeDocxCom: any = VueOfficeDocx;
const VueOfficeExcelCom: any = VueOfficeExcel;
const VueOfficePdfCom: any = VueOfficePdf;

/**
 * @description Base64转Blob
 * @param b64Data
 * @param contentType
 * @param sliceSize
 */
const b64toBlob = (b64Data: any, contentType: any, sliceSize: any) => {
  let b = b64Data.toString();

  b64Data = b.split(",")[1];
  console.log("b64Data :>> ", b64Data);

  let byteCharacters = atob(b64Data);

  console.log("atob(b64Data) :>> ", atob(b64Data));

  let byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    let slice = byteCharacters.slice(offset, offset + sliceSize);

    let byteNumbers = new Array(slice.length);

    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    let byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }
  console.log("byteArrays :>> ", byteArrays);

  let blob = new Blob(byteArrays, { type: contentType });

  return blob;
};

/**
 * @description 获取图片文件url列表
 */
const getUrlList = (data: any) => {
  let arr: any = [];
  let typeArr: any = [];

  data.map((item: any) => {
    typeArr.push(item.fileType);
    if (item.fileData) {
      arr.push(item.fileData);
    } else {
      arr.push("filemd5:" + item.filemd5);
    }
  });
  return arr;
};

const getData = async (index: number) => {
  let res = await props.updated(props.files[index].filemd5, index);
  if (res) {
    isSrcList.value[index] = res;
    fileData.value = res;

    console.log("getData res :>> ", res);
  }
};

/**
 * @description 打开文件预览
 */
const show = async () => {
  if (!props.files.length) return;
  let _index = props.initialIndex ?? 0;
  await getData(_index);
  LjDialogFileRef.value.show();
};

const hideWidget = () => {
  console.log("hideWidget :>> LjFilePreview_PreviewFile", props.closed);
  props.closed && props.closed();
  LjDialogFileRef.value.hide();
};

/**
 * @description 切换
 * @param index 动作
 */
const handleSwitchItem = async (index: number) => {
  console.log("handleSwitchItem index :>> ", index);
  let _index = props.initialIndex ?? 0;
  _index += index;

  if (_index < 0) {
    _index = props.files.length - 1;
  } else if (_index >= props.files.length) {
    _index = 0;
  }

  await getData(_index);
};

onMounted(() => {
  isSrcList.value = getUrlList(props.files);

  document.onkeyup = (e: KeyboardEvent) => {
    e = (window.event as KeyboardEvent) || e;
    console.log("e.code :>> ", e.code);
    if (e.code === "ArrowRight") {
      handleSwitchItem(1);
    } else if (e.code === "ArrowLeft") {
      handleSwitchItem(-1);
    }
    return false;
  };
});

onUnmounted(() => {
  document.onkeyup = null;
});

/**
 * -----------------------------------------------------------------------
 * @description 渲染文件
 */
const RenderFile = () => {
  if (!props.files.length)
    return (
      <>
        <div></div>
      </>
    );
  let _prop = {
    ...drawerDefineProp,
    ...props.drawerProp
  };
  let _type = props.files[props.initialIndex ?? 0].fileType.trim().toLowerCase();
  let _empty = !["doc", "docx", "xls", "xlsx", "pdf"].includes(_type);
  let _name = props.files[props.initialIndex ?? 0].fileName;
  let _slot = {
    header: () => {
      return (
        <div class="flx-1">
          <span class="text-h5-b">{_name}</span>
        </div>
      );
    }
  };

  return (
    <>
      <LjDialog ref={LjDialogFileRef} {..._prop} style={{ height: "50%" }} v-slots={_slot} closed={hideWidget}>
        <div class="file-preview-content ">
          <span class="el-image-viewer__btn el-image-viewer__close" onClick={hideWidget}>
            <el-icon>
              <Close />
            </el-icon>
          </span>
          <span class="el-image-viewer__btn el-image-viewer__prev" onClick={() => handleSwitchItem(-1)}>
            <el-icon>
              <ArrowLeft />
            </el-icon>
          </span>
          <span class="el-image-viewer__btn el-image-viewer__next" onClick={() => handleSwitchItem(1)}>
            <el-icon>
              <ArrowRight />
            </el-icon>
          </span>
          {["doc", "docx"].includes(_type) && <VueOfficeDocxCom src={fileData.value} />}
          {["xls", "xlsx"].includes(_type) && <VueOfficeExcelCom src={fileData.value} style="height: 400px;" />}
          {["pdf"].includes(_type) && <VueOfficePdfCom src={fileData.value} />}
          {_empty && <el-empty description="文件格式不支持预览" />}
        </div>
      </LjDialog>
    </>
  );
};

defineExpose({
  show
});
</script>

<style lang="scss">
.lj-file-views-dialog {
  .lj-dialog {
    display: flex;
    flex-direction: column;
  }
  .el-dialog__header {
    flex-shrink: 0;
  }
  .el-dialog__body {
    flex: 1;
    overflow: auto;
  }
}
.el-image-viewer__close,
.el-image-viewer__prev,
.el-image-viewer__next {
  position: fixed;
}
</style>
