<template>
  <div class="firmware-management-wrap">
    <EdfsWrap class="firmware-table" :customLeft="true">
      <template #title-left>
        <el-breadcrumb :separator-icon="ArrowRight">
          <template v-for="(item, index) in breadcrumbList" :key="index">
            <el-breadcrumb-item
              :class="{ active: index + 1 < breadcrumbList.length }"
              @click="onCrumb(item)"
              >{{ item.name }}</el-breadcrumb-item
            >
          </template>
        </el-breadcrumb>
      </template>
      <EdfsContextMenu
        eventSourceClass="SourceClass"
        :disabledEmpty="false"
        @visibleChange="onVisibleChange"
        ref="contextMenuRef"
      >
        <div class="file-list">
          <div v-for="item in dataList" :key="item.id" @click="onFileOpen(item)">
            <div class="item SourceClass" v-setItem="item">
              <div class="file-header">
                <div></div>
                <Icon
                  class="icon"
                  icon="solar:hamburger-menu-outline"
                  @click="onFile"
                ></Icon>
              </div>
              <div class="file-icon">
                <img
                  :src="
                    item.type === floeType.folder
                      ? Folder
                      : item.isDraft === 0
                      ? Document
                      : Document2
                  "
                />
              </div>
              <div class="file-name">
                <el-input
                  class="edit-input"
                  @click.stop="() => {}"
                  v-if="!!item?.isEdit"
                  v-model="editFileName"
                  :key="item.id + '_edit'"
                  :ref="el => setInputRefs(el, item.id)"
                  @blur="onSaveRename(item)"
                  @keyup.enter="onSaveRename(item)"
                />
                <span v-else>{{ item.name }}</span>
              </div>
            </div>
          </div>
        </div>
        <template #menu="{ menuData }">
          <div
            v-for="menu in dropdownMenu"
            :key="menu.command"
            @click="onCommand(menu.command, menuData)"
          >
            <img
              v-if="menu?.icon"
              :src="menu?.icon"
              width="20"
              style="margin-right: 8px"
            />
            <span :style="{ color: menu.command === 'delete' ? 'red' : 'inherit' }">{{
              menu.label
            }}</span>
          </div>
        </template>
      </EdfsContextMenu>
    </EdfsWrap>
  </div>
  <markdownDrawer
    v-model="isShowMdDrawer"
    v-if="isShowMdDrawer"
    :data="curMarkdown"
    @onSave="onSaveMd"
  />
</template>

<script setup lang="ts">
import {
  floeType,
  operationDropdownMenu,
  breadcrumbList,
  fileDropdownMenu,
} from './utils'
import EdfsWrap from '@/components/dashboard/Edfs-wrap.vue'
import {
  getFileList,
  createFolder,
  updateFolder,
  createdFile,
  updateFile,
  deleteFolder,
  deleteFile,
  getMarkdown,
  updateMarkdown,
  type ContentType,
} from '@/api/module/eam/device/document'
import { isResError, useMessage } from '@/hooks/useMessage.js'
import { ArrowRight } from '@element-plus/icons-vue'
import Folder from '@/assets/image/dashboard/file/folder.svg'
import Upload from '@/assets/image/dashboard/file/upload.svg'
import Document from '@/assets/image/dashboard/file/document.svg'
import Document2 from '@/assets/image/dashboard/file/document2.svg'

import { Icon } from '@/components/dashboard/Icon'
import EdfsContextMenu from '@/components/dashboard/Edfs-context-menu/index.vue'
import markdownDrawer from './components/markdownDrawer.vue'

const dropdownMenu = computed(() => {
  return menuTarget.value
    ? fileDropdownMenu
    : currentFolderId.value === 0
    ? operationDropdownMenu.filter(v => v.command === 'newFolder')
    : operationDropdownMenu.filter(v => v.command === 'newMarkdown')
})

const message = useMessage()

const currentFolderId = ref(0)
watch(
  () => breadcrumbList.value.length,
  () => {
    currentFolderId.value = breadcrumbList.value[breadcrumbList.value.length - 1].id
  }
)

const dataList = ref<any>([])
const loading = ref(false)
async function loadData(id: number = 0) {
  loading.value = true
  const res = await getFileList({
    parentId: id,
  })
  loading.value = false
  if (isResError(res)) return
  dataList.value = res.data
}

async function onDelete(item: any) {
  try {
    let res: any
    await message.delConfirm()
    switch (item.type) {
      case floeType.folder:
        res = await deleteFolder(item.id)
        break
      case floeType.file:
        res = await deleteFile(item.id)
        break
    }
    if (isResError(res)) return
    message.success('删除成功')
    loadData(currentFolderId.value)
  } catch (error) {}
}

const contextMenuRef = ref<any>(null)
function onFile(e: any) {
  contextMenuRef.value.onContextmenu(e)
}

function onNewFolder() {
  const folder = {
    name: '未命名文件夹',
    type: floeType.folder,
    isEdit: true,
  }
  dataList.value.push(folder)
  onRename(folder)
}

function onNewMarkdown() {
  const markdown = {
    name: '未命名文档',
    type: floeType.file,
    isEdit: true,
  }
  dataList.value.push(markdown)
  onRename(markdown)
}

function onCommand(command: string, item: any) {
  switch (command) {
    case 'delete':
      onDelete(item)
      break
    case 'rename':
      onRename(item)
      break
    case 'open':
      onFileOpen(item)
      break
    case 'newFolder':
      onNewFolder()
      break
    case 'newMarkdown':
      onNewMarkdown()
      break
    case 'upload':
      break
  }
}

const menuTarget = ref<HTMLElement | null>(null)
function onVisibleChange(visible: boolean, currentElement: HTMLElement | null) {
  menuTarget.value = currentElement
}

function onCrumb(item: any) {
  const isLast = breadcrumbList.value[breadcrumbList.value.length - 1].id === item.id
  if (isLast) return
  const index = breadcrumbList.value.findIndex(v => v.id === item.id)
  breadcrumbList.value = breadcrumbList.value.slice(0, index + 1)
  loadData(item.id)
}

function onFileOpen(item: any) {
  if (item.isEdit) return
  if (item.type === floeType.folder) {
    breadcrumbList.value.push(item)
    loadData(item.id)
  }
  if (item.type === floeType.file) {
    onOpenMarkdownDrawer(item.id)
  }
}

const editInputRefs = ref<any>({})
function setInputRefs(el: any, id: number) {
  if (el) {
    editInputRefs.value[`editInputRef_${id}`] = el
  }
}

const editFileName = ref('')
async function onSaveRename(item: any) {
  if (!item.isEdit) return
  item.name = editFileName.value
  await nextTick()
  const find = findItem(item.id)
  find.isEdit = false
  await onSaveFile(item)
  editFileName.value = ''
}
async function onRename(item: any) {
  if (!item) return
  const find = findItem(item.id)
  find.isEdit = true
  editFileName.value = item.name
  await nextTick()
  editInputRefs.value[`editInputRef_${item.id}`].focus()
  editInputRefs.value[`editInputRef_${item.id}`].select()
}

const findItem = (id: number) => dataList.value.find((v: any) => v.id === id)

async function onSaveFile(item: any) {
  const isAdd = !item.id
  loading.value = true
  switch (item.type) {
    case floeType.folder:
      await saveFolder(isAdd, item)
      break
    case floeType.file:
      await saveFile(isAdd, item)
      break
  }

  loadData(currentFolderId.value)
}

function getPath() {
  return currentFolderId.value === 0
    ? ''
    : breadcrumbList.value[breadcrumbList.value.length - 1].path
}

async function saveFolder(isAdd: boolean, item: any) {
  getPath()
  let res
  if (isAdd) {
    res = await createFolder({
      name: item.name,
      parentId: currentFolderId.value,
      path: getPath(),
    })
  } else {
    res = await updateFolder({
      id: item.id,
      name: item.name,
      parentId: currentFolderId.value,
      path: getPath(),
    })
  }
  if (isResError(res)) return
}
async function saveFile(isAdd: boolean, item: any) {
  let res
  if (isAdd) {
    res = await createdFile({
      name: item.name + '.md',
      parentId: currentFolderId.value,
      isDraft: 1,
      path: getPath(),
    })
  } else {
    res = await updateFile({
      id: item.id,
      name: item.name,
      parentId: currentFolderId.value,
      path: getPath(),
    })
  }
  if (isResError(res)) return
}

const fullscreenLoading = ref()

function openFullScreen() {
  fullscreenLoading.value = ElLoading.service({
    lock: true,
    text: '数据加载中请稍等...',
    target: document.querySelector('.firmware-management-wrap') as HTMLElement,
  })
}
watch(loading, val => {
  if (val) {
    openFullScreen()
  } else {
    fullscreenLoading.value?.close()
  }
})

//  markdown 操作
const curMarkdown = ref() as Ref<ContentType & { fileName: string }>
const curMdId = ref()

const isShowMdDrawer = ref(false)
async function onOpenMarkdownDrawer(id: number) {
  curMdId.value = id
  const res = await getMarkdown({ folderId: id })
  if (isResError(res)) return
  curMarkdown.value = Object.assign({}, res.data, { fileName: findItem(id).name })

  isShowMdDrawer.value = true
}

async function onSaveMd(isDraft: 0 | 1, data: string) {
  const res = await updateMarkdown({
    content: data,
    folderId: curMdId.value,
    isDraft,
  })

  if (isResError(res)) return
  message.success(isDraft === 1 ? '保存成功' : '发布成功')
  isShowMdDrawer.value = false
  curMarkdown.value = null as any
  loadData(currentFolderId.value)
}
onMounted(() => {
  loadData()
})
</script>

<style scoped lang="scss">
.firmware-management-wrap {
  width: 100%;
  height: 100%;
  :deep(.el-breadcrumb) {
    margin-left: 4px;
  }
  .active {
    :deep(.el-breadcrumb__inner) {
      color: var(--el-color-primary);
      font-weight: 800;
      cursor: pointer;
    }
  }
  .file-list {
    user-select: none;
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    .item {
      width: 90px;
      height: 110px;
      display: flex;
      cursor: pointer;
      align-items: center;
      flex-direction: column;
      justify-content: center;
      border-radius: 3px;
      padding-bottom: 4px;
      .file-header {
        visibility: hidden;
        width: 100%;
        height: calc(100% - 66px - 24px);
        display: flex;
        align-items: center;
        padding: 0 8px;
        box-sizing: border-box;
        justify-content: space-between;
        .icon {
          flex-direction: end;
          color: var(--icon-color);
          :hover {
            color: var(--icon-hover-color);
          }
        }
      }

      .file-icon {
        width: 66px;
        height: 66px;
        img {
          width: 100%;
          height: 100%;
        }
      }
      .file-name {
        height: 24px;
        line-height: 24px;
        font-size: 14px;
        color: var(--label-color);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 100%;
        text-align: center;
        .edit-input {
          width: 100%;
          height: 100%;
          margin-bottom: 4px;
        }
      }
      &:hover {
        background-color: var(--mask-bg);
        .file-header {
          visibility: visible;
        }
      }
    }
  }
}
</style>
