<template>
  <div class="panorama con">
    <div class="top">
      <crumbs
        v-if="!lastestUsedSearchKey"
        :list="folderPath"
        :rootName="$i18n.t('gather.pano')"
        @click-path="onClickPath"
      />
      <div v-if="lastestUsedSearchKey" class="">{{$i18n.t("gather.pano")}}</div>
    </div>
    <div class="second-line">
      <template v-if="!searchKey">
        <div class="btn">
          <button @mouseover.stop="showList = true" @click="onUploadFile" class="ui-button submit">
            <span>{{ upload_material }}</span>
            <i
              class="iconfont icon-material_prompt"
              v-tooltip="pano_size"
            />
            <upload ref="uploadFile" :failString="pano_fail" :limitFailStr="pano_limit" accept-type=".jpg"
              media-type="image" :limit="120" @file-change="onFileChange"></upload>
          </button>
        </div>
        <button
          class="ui-button submit"
          @click="isShowNewFolder = true"
        >
          {{$i18n.t(`gather.new_folder`)}}
        </button>
        <button
          class="ui-button cancel"
          :class="{disable: selectedList.length === 0}"
          @click="onClickMoveFolder"
        >
          {{$i18n.t(`gather.move_folder`)}}
        </button>
      </template>
      <div class="filter">
        <div :class="{ active: isFilterFocus }" @focusin="onFilterFocus" @focusout="onFilterBlur">
          <i class="iconfont icon-works_search search"></i>
          <input type="text" v-model="searchKey" :placeholder="serch_material" />
          <i v-if="searchKey" @click="searchKey = ''" class="iconfont icontoast_red del"></i>
        </div>
      </div>
    </div>
    <div class="list">
      <tableList
        @selection-change="
          (data) => {
            selectedList = data;
          }
        "
        @request-more-data="getMoreMaterialItem"
        :canRequestMoreData="hasMoreData && !isRequestingMoreData"
        :header="tabHeader"
        :showLine="true"
        :selection="lastestUsedSearchKey ? false : true"
        :data="list"
        class="table-list"
        ref="table-list"
      >
        <!-- 插到tableList组件各个header插槽，并通过插槽的headerItem作用域拿到表头各项 -->
        <div slot-scope="{ headerItem }" slot="header">
          {{ headerItem.name && $i18n.t(`zh_key.${headerItem.name}`) }}
        </div>
        <!-- 内容各单元格 -->
        <div slot-scope="{ itemData, lineData, headerItem }" slot="tableItem" style="width: 100%">
          <!-- 操作型单元格 -->
          <div class="handle" v-if="headerItem.canclick">
            <i
              v-if="lineData.type !== 'dir'"
              class="iconfont icon-material_operation_image hover-tips"
              @click="(showCover = true), (popupItem = lineData)"
            >
              <div>
                <div class="remark">{{ edit_cover }}</div>
              </div>
            </i>

            <i
              class="iconfont icon-material_operation_editor hover-tips"
              @click="onClickRename(lineData)"
            >
              <div>
                <div class="remark">{{ rename }}</div>
              </div>
            </i>
            <i
              class="iconfont icon-material_operation_delete hover-tips-warn"
              @click="del(lineData)"
            >
              <div>
                <div class="remark">{{ deltips }}</div>
              </div>
            </i>
          </div>
          <!-- 图片型单元格 -->
          <div
            v-else-if="headerItem.type == 'image' && lineData.type !== 'dir'"
            class="img"
            @click="previewImage(lineData)"
          >
            <img :src="itemData + $imgsuffix"
              alt="" />
          </div>
          <div
            v-else-if="headerItem.type == 'image' && lineData.type === 'dir'"
            class="img dirIcon"
          >
            <img
              :src="require('@/assets/images/icons/folder-blue.png')"
              alt=""
              @click="onClickFolder(lineData)"
            />
          </div>



          <!-- 文字型单元格 -->
          <div
            v-else
            class="textItem"
          >
          
          
            <!-- 名称 -->
            <div v-if="headerItem.key === 'name'" class="name">
              
              <!-- 不是搜索出来的 -->
              <div v-if="!lastestUsedSearchKey" class="not-search-res">
                <!-- 文件夹名称 -->
                <div
                  v-if="lineData.type === 'dir'"
                  class="dirName"
                  @click="onClickFolder(lineData)"
                >
                  {{ itemData || "-" }}
                </div>
                <!-- 素材名称 -->
                <div v-else class="not-dir">
                  {{ itemData || "-" }}
                </div>
              </div>
              <!-- end of 不是搜索出来的 -->
              
              <!-- 搜索出来的 -->
              <div v-if="lastestUsedSearchKey" class="search-res">
                <!-- 文件夹名称 -->
                <div
                  v-if="lineData.type === 'dir'"
                  class="dirName"
                >
                  <div
                    class="self-name"
                    @click="onClickFolder(lineData)"
                  >
                    {{ itemData || "-" }}
                  </div>
                  <div class="parent-name-wrap">
                    {{$i18n.t('gather.dir')}} <span class="parent-name" @click="onClickParentFolder(lineData)">{{lineData.dirId === 1 ? $i18n.t('gather.root_dir') : lineData.dirName}}</span>
                  </div>
                </div>
                <!-- 素材名称 -->
                <div v-else class="not-dir">
                  <div class="self-name">
                    {{ itemData || "-" }}
                  </div>
                  <div class="parent-name-wrap">
                    {{$i18n.t('gather.dir')}} <span class="parent-name" @click="onClickParentFolder(lineData)">{{lineData.dirId === 1 ? $i18n.t('gather.root_dir') : lineData.dirName}}</span>
                  </div>
                </div>
              </div>
              <!-- end of 搜索出来的 -->
              
            </div>
            <!-- end of 名称 -->
            
            
            <!-- 不是名称 -->
            <div v-else class="not-name">
              {{ itemData || "-" }}
            </div>
            <!-- end of 不是名称 -->

            
          </div>
          <!-- end of 文字型单元格 -->



        </div>
      </tableList>
      <UploadTaskList
        class="upload-task-list"
        fileType="IMAGE"
        :taskList="uploadListForUI"
        :targetFolderId="lastestUsedSearchKey ? -1 : currentFolderId"
        @cancel-task="onCancelTask"
      />
      <div class="total-number" v-if="list.length !== 0 || hasMoreData">{{ had_load }}</div>
      <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
        <img :src="$noresult" alt="" />
        <span>{{ no_serch_result }}</span>
      </div>
      <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
        <img :src="config.empty" alt="" />
        <span>{{ no_material_result }}</span>
        <button @click="$refs.uploadFile.click()" class="upload-btn-in-table">{{ upload_material }}</button>
      </div>
    </div>

    <CreateFolder
      v-if="isShowNewFolder"
      :validate=validateNewFolderName
      @close="isShowNewFolder = false"
      @submit="onSubmitNewFolder"
    />
    <RenameFolder
      v-if="isShowRenameFolder"
      :oldName="popupItem.name"
      :validate=validateRenameFolderName
      @close="isShowRenameFolder = false"
      @submit="onSubmitRenameFolder"
    />
    <MoveFolder
      v-if="isShowMoveFolder"
      :folderTree="folderTree"
      :selectedList="selectedList"
      @close="isShowMoveFolder = false"
      @submit="onSubmitMoveFolder"
    />
    <rename
      v-if="showRename" 
      :item="popupItem"
      @rename="handleRename"
      @close="showRename = false" 
    />
    <preview
      ref="image-previewer"
      :sceneCodeList="list.map(item => item.sceneCode)"
      :imageTitleList="list.map(item => item.name)"
      @click-delete="onClickDeleteInPreview"
    />
    <cover
      @panocover="handlePanoCover"
      :item="popupItem"
      v-if="showCover"
      @close="showCover = false"
    />
  </div>
</template>

<script>
import config from "@/config";
import tableList from "@/components/table/index.vue";
import crumbs from "@/components/crumbs/index.vue";
import { data } from "./pano";
import rename from "../popup/rename";
import preview from "../popup/panoImagePreviewer.vue";
import cover from "../popup/cover";
import Upload from "@/components/shared/uploads/UploadMultiple";
import { getImgWH, changeByteUnit } from "@/utils/file";
import UploadTaskList from "../components/uploadList1.1.0.vue";
import { debounce } from "@/utils/other.js"
import { mapState } from 'vuex';
import { i18n } from "@/lang"
import folderMixinFactory from "../folderMixinFactory.js";

import {
  getMaterialList,
  uploadMaterial,
  editMaterial,
  delMaterial,
  uploadCover,
  checkMStatus,
  checkUserSize
} from "@/api";


const TYPE = "pano";
const LONG_POLLING_INTERVAL = 5;
const folderMixin = folderMixinFactory(TYPE)

export default {
  mixins: [
    folderMixin,
  ],
  name: 'Pano',
  components: {
    tableList,
    crumbs,
    rename,
    cover,
    preview,
    Upload,
    UploadTaskList,
  },
  data() {
    return {
      upload_material: i18n.t("gather.upload_material"),
      serch_material: i18n.t("gather.serch_material"),
      no_serch_result: i18n.t("gather.no_serch_result"),
      no_material_result: i18n.t("gather.no_material_result"),
      pano_size: i18n.t("gather.pano_size"),
      pano_fail: i18n.t("gather.pano_fail"),
      pano_limit: i18n.t("gather.pano_limit"),
      edit_cover: i18n.t("gather.edit_cover"),
      rename: i18n.t("gather.rename"),
      deltips: i18n.t("gather.delete"),

      config,
      showRename: false,
      showCover: false,
      showList: false,
      popupItem: null,
      tabHeader: data,

      // 因为searchKey的变化经过debounce、异步请求的延时，才会反映到数据列表的变化上，所以是否显示、显示哪种无数据提示，也要等到数据列表变化后，根据数据列表是否为空，以及引发本次变化的那个searchKey瞬时值来决定。本变量就是用来保存那个瞬时值。
      lastestUsedSearchKey: '',
      isFilterFocus: false,
      searchKey: "",
      list: [],
      hasMoreData: true,
      isRequestingMoreData: false,
    };
  },
  computed: {
    ...mapState({
      uploadListForUI: 'uploadStatusListPano',
    }),
    needLongPolling() {
      return this.uploadListForUI.some((item) => {
        return item.status === 'LOADING' && item.ifKnowProgress === false
      })
    },
    had_load() {
      return i18n.t("gather.had_load", { msg: this.list.length })
    }
  },
  mounted() {
  },
  watch: {
    needLongPolling: {
      handler: function (newVal) {
        if (!newVal) {
          this.clearinter();
        } else {
          this.clearinter();
          this.interval = setInterval(() => {
            this._checkMStatus();
          }, LONG_POLLING_INTERVAL * 1000);
        }
      },
      immediate: true,
    },
    searchKey: {
      handler: function () {
        this.refreshListDebounced()
      },
      immediate: false,
    },
  },
  methods: {
    onUploadFile() {
      checkUserSize({}, (data) => {
        //判断已用是否大于3G
        if ((data.data / 1024 / 1024) > 3) {
          this.$alert({ content: i18n.t("tips_code.FAILURE_3024") });
        } else {
          this.$refs.uploadFile.click()
        }
      })
    },
    onFilterFocus() {
      this.isFilterFocus = true
    },
    onFilterBlur() {
      this.isFilterFocus = false
    },
    refreshListDebounced: debounce(function () {
      this.list = []
      this.isRequestingMoreData = false
      this.hasMoreData = true
      this.$refs['table-list'].requestMoreData()
    }, 500, false),
    clearinter() {
      this.interval && clearInterval(this.interval);
      this.interval = null;
    },
    handleRename(newName) {
      editMaterial(
        {
          id: this.popupItem.id,
          name: newName,
        },
        () => {
          this.$msg.success(i18n.t("gather.edit_success"));
          const index = this.list.findIndex((eachItem) => {
            return eachItem.id === this.popupItem.id
          })
          if (index >= 0) {
            this.list[index].name = newName
          } else {
            console.error('在素材列表里没找到要重命名的那一项！');
          }
          this.showRename = false;
          this.popupItem = null;
        }
      );
    },
    handlePanoCover(data) {
      if (data.indexOf("http") > -1) {
        this.showCover = false;
        this.popupItem = "";
        return;
      }
      uploadCover({ file: data, filename: "cover.jpg" }, (res) => {
        if (res.code == 0) {
          editMaterial(
            {
              id: this.popupItem.id,
              icon: res.data,
            },
            () => {
              this.$msg.success(i18n.t("gather.setting_success"));

              const index = this.list.findIndex((eachItem) => {
                return eachItem.id === this.popupItem.id
              })
              if (index >= 0) {
                this.isRequestingMoreData = true
                const lastestUsedSearchKey = this.searchKey
                getMaterialList(
                  {
                    dirId: this.currentFolderId,
                    pageNum: index + 1,
                    pageSize: 1,
                    type: TYPE,
                  },
                  (data) => {
                    const newData = data.data.list.map((i) => {
                      i.fileSize = changeByteUnit(Number(i.fileSize));
                      return i;
                    });
                    this.list.splice(index, 1, newData[0])
                    this.showCover = false;
                    this.popupItem = "";
                    this.isRequestingMoreData = false
                    this.lastestUsedSearchKey = lastestUsedSearchKey
                  },
                  () => {
                    this.isRequestingMoreData = false
                    this.lastestUsedSearchKey = lastestUsedSearchKey
                    this.showCover = false;
                    this.popupItem = "";
                  }
                )
              } else {
                console.error('在素材列表里没找到要编辑封面的那一项！');
                this.showCover = false;
                this.popupItem = "";
              }
            }
          );
        }
      });
    },
    _checkMStatus() {
      let needPollingTaskList = this.uploadListForUI.filter((item) => item.status === 'LOADING' && item.ifKnowProgress === false);
      if (needPollingTaskList.length > 0) {
        checkMStatus(
          {
            ids: needPollingTaskList.map((item) => item.backendId),
            islongpolling: true,
          },
          (res) => {
            // 1切图中，2失败，3成功
            res.data.forEach(eachRes => {
              if (eachRes.status === 2) {
                const index = this.uploadListForUI.findIndex(eachTask => eachTask.backendId === eachRes.id)
                index >= 0 && (this.uploadListForUI[index].status = 'FAIL')
                index >= 0 && (this.uploadListForUI[index].statusText = this.$msg.success(i18n.t("gather.material_cutting_fail")))
              } else if (eachRes.status === 3) {
                const index = this.uploadListForUI.findIndex(eachTask => eachTask.backendId === eachRes.id)
                index >= 0 && (this.uploadListForUI.splice(index, 1))
                index >= 0 && this.refreshListDebounced()
              }
            });
          }
        );
      }
    },
    onClickRename(lineData) {
      this.popupItem = lineData
      if (lineData.type !== 'dir') {
        this.showRename = true
      } else {
        this.isShowRenameFolder = true
      }
    },
    del(item) {
      if (item.type === 'dir') {
        this.delFolder(item.id, (lastestUsedSearchKey) => {
          getMaterialList(
            {
              dirId: this.currentFolderId,
              pageNum: this.list.length,
              pageSize: 1,
              searchKey: this.searchKey,
              type: TYPE,
            },
            (data) => {
              const index = this.list.findIndex((eachItem) => {
                return eachItem.id === item.id
              })
              if (index >= 0) {
                this.list.splice(index, 1)
                const newData = data.data.list.map((i) => {
                  i.fileSize = changeByteUnit(Number(i.fileSize));
                  return i;
                });
                this.list = this.list.concat(newData)
                if (this.list.length === data.data.total) {
                  this.hasMoreData = false
                }
                if (this.list.length === 0) {
                  this.$refs['image-previewer'].onClickClose()
                }
              } else {
                console.error('在素材列表里没找到要删除的那一项！');
              }

              this.isRequestingMoreData = false
              this.lastestUsedSearchKey = lastestUsedSearchKey
            },
            () => {
              this.isRequestingMoreData = false
              this.lastestUsedSearchKey = lastestUsedSearchKey
            }
          )
        })
      } else {
        this.$confirm({
          title: i18n.t("gather.delete_material"),
          content: i18n.t("gather.comfirm_delete_material"),
          okText: i18n.t("gather.delete"),
          ok: () => {
            delMaterial(item.id, () => {
              this.$msg.success(i18n.t("gather.delete_success"));
              this.isRequestingMoreData = true
              const lastestUsedSearchKey = this.searchKey
              getMaterialList(
                {
                  dirId: this.currentFolderId,
                  pageNum: this.list.length,
                  pageSize: 1,
                  searchKey: this.searchKey,
                  type: TYPE,
                },
                (data) => {
                  const index = this.list.findIndex((eachItem) => {
                    return eachItem.id === item.id
                  })
                  if (index >= 0) {
                    this.list.splice(index, 1)
                    const newData = data.data.list.map((i) => {
                      i.fileSize = changeByteUnit(Number(i.fileSize));
                      return i;
                    });
                    this.list = this.list.concat(newData)
                    if (this.list.length === data.data.total) {
                      this.hasMoreData = false
                    }
                    if (this.list.length === 0) {
                      this.$refs['image-previewer'].onClickClose()
                    }
                  } else {
                    console.error('在素材列表里没找到要删除的那一项！');
                  }

                  this.isRequestingMoreData = false
                  this.lastestUsedSearchKey = lastestUsedSearchKey
                },
                () => {
                  this.isRequestingMoreData = false
                  this.lastestUsedSearchKey = lastestUsedSearchKey
                }
              )
            });
          },
        });
      }
    },
    previewImage(targetItem) {
      const index = this.list.findIndex((eachItem) => {
        return eachItem.id === targetItem.id
      })
      this.$refs['image-previewer'].show(index)
    },
    onFileChange(e) {
      e.files.forEach(async (eachFile, i) => {
        if (
          eachFile.type.indexOf("jpeg") <= -1
        ) {
          setTimeout(() => {
            this.$msg({
              message: `“${eachFile.name}”${i18n.t("gather.pano_fail")}`,
              type: "warning",
            });
          }, i * 100);
          return;
        }

        if (eachFile.name.substring(0, eachFile.name.lastIndexOf(".")).length > 50) {
          setTimeout(() => {
            this.$msg({
              message: `“${eachFile.name}”${i18n.t("gather.too_long_word")}`,
              type: "warning",
            });
          }, i * 100);
          return;
        }

        let WHRate = null
        try {
          const { width, height } = await getImgWH(eachFile)
          WHRate = width / height
        } catch (e) {
          console.error('获取图像宽高失败：', e)
          setTimeout(() => {
            this.$msg({
              message: `“${eachFile.name}”${i18n.t("gather.pano_fail")}`,
              type: "warning",
            });
          }, i * 100);
          return
        }
        if (WHRate !== 2) {
          setTimeout(() => {
            this.$msg({
              message: `“${eachFile.name}”${i18n.t("gather.pano_fail")}`,
              type: "warning",
            });
          }, i * 100);
          return
        }

        let itemInUploadList = {
          title: eachFile.name,
          ifKnowProgress: true,
          progress: 0,
          status: 'LOADING',
          statusText: i18n.t("gather.uploading_material"),
          uid: `u_${this.$randomWord(true, 8, 8)}`,
          abortHandler: null,
          backendId: '',
          parentFolderId: this.currentFolderId,
        };

        itemInUploadList.abortHandler = uploadMaterial(
          {
            dirId: this.currentFolderId,
            file: eachFile,
            tempId: itemInUploadList.uid,
            type: TYPE,
          },
          (response) => { // 上传成功
            itemInUploadList.statusText = i18n.t("gather.cutting")
            itemInUploadList.ifKnowProgress = false
            itemInUploadList.backendId = response.data.id
          },
          (err) => {
            if (err.statusText === 'abort') { // 用户取消了上传任务。
              const index = this.uploadListForUI.findIndex((eachItem) => {
                return eachItem.uid === itemInUploadList.uid
              })
              this.uploadListForUI.splice(index, 1)
            } else {
              itemInUploadList.status = 'FAIL'
              itemInUploadList.statusText = i18n.t("gather.material_upload_fail")
            }
          },
          (progress) => {
            itemInUploadList.progress = progress
          }
        )

        this.uploadListForUI.push(itemInUploadList);
      })
    },
    onCancelTask(uid) {
      const index = this.uploadListForUI.findIndex((eachItem) => {
        return eachItem.uid === uid
      })
      if (this.uploadListForUI[index].status === 'LOADING') {
        this.uploadListForUI[index].abortHandler.abort()
      } else {
        this.uploadListForUI.splice(index, 1)
      }
    },
    getMoreMaterialItem(islongpolling = null) {
      this.isRequestingMoreData = true
      const lastestUsedSearchKey = this.searchKey
      getMaterialList(
        {
          dirId: this.currentFolderId,
          pageNum: Math.floor(this.list.length / config.PAGE_SIZE) + 1,
          pageSize: config.PAGE_SIZE,
          searchKey: this.searchKey,
          type: TYPE,
          islongpolling
        },
        (data) => {
          const newData = data.data.list.map((i) => {
            if (i.type !== 'dir') {
              i.fileSize = changeByteUnit(Number(i.fileSize));
            }
            return i;
          });
          this.list = this.list.concat(newData)
          if (this.list.length === data.data.total) {
            this.hasMoreData = false
          }
          this.isRequestingMoreData = false
          this.lastestUsedSearchKey = lastestUsedSearchKey
        },
        () => {
          this.isRequestingMoreData = false
          this.lastestUsedSearchKey = lastestUsedSearchKey
        }
      );
    },
    onClickDeleteInPreview(index) {
      this.del(this.list[index])
    },
  },
};
</script>

<style lang="less" scoped>

</style>
<style lang="less" scoped>
@import "../style.less";
</style>