<template>
  <div
    class="tree-page grid grid-cols-[auto_1fr] grid-rows-[48px_48px_1fr] gap-x-4 gap-y-3 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
    <PmsTree
      class="row-span-3"
      @node-click="handleFileNodeClick"
      @success="successList"
      :currentId="queryParams.classId"
      :deviceId="id" />

    <el-form
      class="search-panel bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 gap-8 flex items-center justify-between"
      :model="queryParams"
      ref="queryFormRef"
      :inline="true"
      label-width="68px">
      <div class="flex items-center gap-8">
        <el-form-item :label="t('file.name')" prop="filename">
          <el-input
            v-model="queryParams.filename"
            :placeholder="t('file.nameHolder')"
            size="default"
            clearable
            @keyup.enter="handleQuery"
            class="!w-240px" />
        </el-form-item>
        <el-form-item v-show="false" :label="t('file.fileType')" prop="fileType">
          <el-select
            v-model="queryParams.fileType"
            :placeholder="t('file.fileTypeHolder')"
            size="default"
            clearable
            class="!w-200px">
            <el-option
              v-for="dict in getStrDictOptions(DICT_TYPE.PMS_FILE_TYPE)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value" />
          </el-select>
        </el-form-item>
      </div>
      <el-form-item>
        <el-button size="default" @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px" />{{ t('file.search') }}
        </el-button>
        <el-button size="default" @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px" />{{ t('file.reset') }}
        </el-button>
        <el-button
          type="primary"
          size="default"
          :loading="uploadLoading"
          @click="openForm('create')">
          <Icon icon="ep:plus" class="mr-5px" />{{ t('file.upload') }}
        </el-button>
      </el-form-item>
    </el-form>

    <div
      class="breadcrumb-panel bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-4 flex items-center justify-between">
      <el-breadcrumb separator=">" class="breadcrumb-container">
        <el-breadcrumb-item
          v-for="(item, index) in breadcrumbs"
          :key="index"
          @click="handleBreadcrumbClick(index)"
          :class="{ 'current-crumb': index === breadcrumbs.length - 1 }"
          class="custom-breadcrumb-item">
          {{ item.name }}
        </el-breadcrumb-item>
      </el-breadcrumb>
      <el-input
        v-model="queryParams.allName"
        :placeholder="'在' + breadcrumbs[breadcrumbs.length - 1].name + '下搜索'"
        size="default"
        style="width: 250px"
        @input="searchFolderAndFile" />
    </div>

    <div class="table-panel bg-white dark:bg-[#1d1e1f] rounded-lg shadow overflow-hidden p-3">
      <zm-table
        :loading="formLoading"
        :data="list"
        :stripe="true"
        :show-overflow-tooltip="true"
        settings-cache-key="system-tree-file-list"
        @row-dblclick="inContent"
        class="custom-table">
        <zm-table-column :label="t('file.name')" align="left" prop="filename" min-width="300">
          <template #default="scope">
            <div style="display: flex; align-items: center; gap: 5px">
              <Icon v-if="scope.row.fileType === 'content'" icon="fa:folder-open" color="orange" />
              <Icon
                v-else-if="scope.row.fileType === 'device'"
                icon="fa:folder-open"
                color="blue" />
              <Icon
                v-else-if="
                  scope.row.fileType === 'pic' ||
                  scope.row.fileClassify === 'jpg' ||
                  scope.row.fileClassify === 'png' ||
                  scope.row.fileClassify === 'JPG'
                "
                icon="ep:picture-filled"
                color="#2183D1" />
              <Icon
                v-else-if="
                  scope.row.fileType === 'file' &&
                  (scope.row.fileClassify === 'pdf' || scope.row.fileClassify === 'PDF')
                "
                icon="fa-solid:file-pdf"
                color="#E20012" />
              <Icon
                v-else-if="
                  scope.row.fileType === 'file' &&
                  (scope.row.fileClassify === 'doc' || scope.row.fileClassify === 'docx')
                "
                icon="fa:file-word-o"
                color="blue" />
              <Icon
                v-else-if="
                  scope.row.fileType === 'file' &&
                  (scope.row.fileClassify === 'xls' || scope.row.fileClassify === 'xlsx')
                "
                icon="fa-solid:file-excel"
                color="#107C41" />
              <Icon
                v-else-if="scope.row.fileType === 'file' && scope.row.fileClassify === 'txt'"
                icon="fa:file-text-o" />
              <Icon
                v-else-if="scope.row.fileType === 'file' && scope.row.fileClassify === 'mp4'"
                icon="fa:play-circle-o"
                color="#009fff" />
              <Icon
                v-else-if="
                  scope.row.fileType === 'file' &&
                  (scope.row.fileClassify === 'ppt' || scope.row.fileClassify === 'pptx')
                "
                icon="fa-solid:file-powerpoint"
                color="#C43E1C" />
              <Icon v-else icon="fa-solid:file-alt" />
              {{ scope.row.filename }}
            </div>
          </template>
        </zm-table-column>
        <zm-table-column :label="t('file.fileType')" align="center" prop="fileType">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.PMS_FILE_TYPE" :value="scope.row.fileType" />
          </template>
        </zm-table-column>
        <zm-table-column :label="t('file.fileSize')" align="center" prop="fileSize" />
        <zm-table-column :label="t('file.dept')" align="center" prop="deptName" />
        <zm-table-column
          :label="t('file.device')"
          align="center"
          prop="deviceCode"
          min-width="220" />
        <zm-table-column
          :label="t('file.operation')"
          align="center"
          width="160"
          fixed="right"
          action>
          <template #default="scope">
            <div class="flex items-center justify-center">
              <el-button
                type="primary"
                v-if="scope.row.fileType !== 'content'"
                link
                @click="handleDownload(scope.row.filePath)"
                v-hasPermi="['rq:iot-info:download']">
                <Icon icon="ep:download" />{{ t('file.dow') }}
              </el-button>
              <el-button
                type="danger"
                v-if="scope.row.fileType !== 'content'"
                link
                @click="deleteInfo(scope.row.id)"
                v-hasPermi="['rq:iot-info:download']">
                <Icon icon="ep:delete" />{{ t('file.delete') }}
              </el-button>
            </div>
          </template>
        </zm-table-column>
      </zm-table>
    </div>
  </div>

  <IotInfoFormTree
    ref="formRef"
    @success="getList"
    :deviceId="deviceId"
    :nodeId="nodeId"
    :classId="clickNodeId" />
</template>
<script lang="ts" setup>
import IotInfoFormTree from '@/views/pms/iotinfo/IotInfoFormTree.vue'
import * as IotInfoApi from '@/api/pms/iotinfo'
import { ref, onMounted } from 'vue'
import { Base64 } from 'js-base64'

import PmsTree from '@/views/system/tree/PmsTree.vue'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import { IotInfoClassifyApi } from '@/api/pms/info'
import { IotTreeApi } from '@/api/system/tree'
defineOptions({ name: 'IotTree' })

type TreeKey = number | string

interface QueryParams {
  pageNo: number
  pageSize: number
  filename: string | null
  fileType: string | null
  createTime: string[]
  deviceId: TreeKey | null
  classId: TreeKey | null
  deptId?: TreeKey
  allName: string | null
}

interface BreadcrumbItem {
  id: TreeKey | null
  name: string
  type?: string
}

interface FileRow {
  id: TreeKey
  originId?: TreeKey
  parentId?: TreeKey
  name?: string
  filename?: string
  fileType?: string
  filePath?: string
  fileSize?: string
  fileClassify?: string
  deptName?: string
  deviceCode?: string
  type?: string
}

interface IotInfoFormTreeExpose {
  open: (type: string, id?: number) => void
}

const uploadLoading = ref(false)

const searchFolderAndFile = async () => {
  formLoading.value = true
  const data = await IotInfoApi.IotInfoApi.getAllChildContentFile(queryParams)
  list.value = data
  formLoading.value = false
  queryParams.filename = ''
}
const topNodeId = ref<TreeKey | null>(null)
const successList = async (id?: TreeKey) => {
  if (id === undefined) return

  queryParams.classId = id
  topNodeId.value = id
  const rootItem = breadcrumbs.value.find((item) => item.type === 'root')
  if (rootItem) {
    rootItem.id = id
  }

  await getList()
  // queryParams.classId = ''
}

const queryFormRef = ref() // 搜索的表单
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const { params } = useRoute() // 查询参数
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const list = ref<FileRow[]>([]) // 列表的数据
// const total = ref(0) // 列表的总页数
const id = ref(0)
const queryParams = reactive<QueryParams>({
  pageNo: 1,
  pageSize: 10,
  filename: null,
  fileType: null,
  createTime: [],
  deviceId: null,
  classId: null,
  deptId: undefined,
  allName: null
})
const handleDownload = async (url?: string) => {
  if (!url) return
  try {
    formLoading.value = true
    const response = await fetch(url)
    const blob = await response.blob()
    const downloadUrl = window.URL.createObjectURL(blob)

    const link = document.createElement('a')
    link.href = downloadUrl
    link.download = url.split('/').pop()! // 自动获取文件名‌:ml-citation{ref="3" data="citationList"}
    link.click()

    URL.revokeObjectURL(downloadUrl)
    formLoading.value = false
  } catch (error) {
    console.error('下载失败:', error)
  }
}
const deleteInfo = async (id: TreeKey) => {
  await message.delConfirm()
  await IotInfoApi.IotInfoApi.deleteIotInfo(Number(id)).then((res) => {
    if (res) {
      message.success('文件删除成功')
      getList()
    } else {
      message.error('文件删除失败')
    }
  })
}
const formRef = ref<IotInfoFormTreeExpose>()
const openForm = async (type: string, id?: number) => {
  // if (classType.value==='dept'){
  //   message.error(t('common.deptChoose'))
  //   return;
  // }
  uploadLoading.value = true
  if (!queryParams.classId) {
    message.error(t('common.leftNode'))
    uploadLoading.value = false
    return
  }
  formRef.value?.open(type, id)
  await new Promise<void>((resolve) => {
    setTimeout(() => {
      resolve() // 操作完成后resolve
    }, 2000) // 模拟2秒耗时
  })
  uploadLoading.value = false
}
const deviceId = ref('')
const clickNodeId = ref('')
const nodeId = ref('')

const breadcrumbs = ref<BreadcrumbItem[]>([
  { id: null, name: '科瑞石油技术', type: 'root' } // 根节点
])

// 共享的面包屑更新逻辑
const updateBreadcrumbs = async (node: FileRow) => {
  // 查找当前节点是否已在面包屑中
  const currentIndex = breadcrumbs.value.findIndex((item) => item.id === node.id)

  if (currentIndex > -1) {
    // 如果已存在则截断后面的节点
    breadcrumbs.value = breadcrumbs.value.slice(0, currentIndex + 1)
  } else {
    // 新增节点到面包屑
    breadcrumbs.value.push({ id: node.id, name: node.filename || node.name || '' })
  }

  // 更新表格数据
  queryParams.classId = node.id
  const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
  list.value = data
}

// 表格行点击事件
const inContent = async (row: FileRow) => {
  if (row.fileType != 'content') {
    if (!row.filePath) return

    window.open(
      'http://doc.deepoil.cc:8012/onlinePreview?url=' +
        encodeURIComponent(Base64.encode(row.filePath))
    )
    return
  }
  queryParams.filename = ''
  formLoading.value = true
  // 调用共享方法更新面包屑和表格
  await updateBreadcrumbs(row)
  // 可以添加其他表格行点击需要的逻辑
  queryParams.classId = row.id
  nodeId.value = String(row.id)
  const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
  formLoading.value = false
  list.value = data
}

// 文件树节点点击事件
const handleFileNodeClick = async (row: FileRow) => {
  queryParams.filename = ''
  const parentItems = await IotTreeApi.getParentIds(row.id)
  breadcrumbs.value = []
  parentItems.forEach((item) => {
    breadcrumbs.value.push({ id: item.id, name: item.name, type: 'root' })
  })

  queryParams.classId = row.id
  if (row.type == 'device') {
    id.value = Number(row.originId)
  }

  if (row.type === 'device') {
    deviceId.value = String(row.originId)
    const queryParam = {
      deviceId: row.originId,
      pageNo: 1,
      pagesize: 10
    }
    const data = await IotInfoClassifyApi.getIotInfoClassifyPage(queryParam)
    if (data) {
      const target = data.filter((item) => item.parentId === 0)
      clickNodeId.value = String(target[0]?.id ?? '')
    }
  } else if (row.type === 'file') {
    clickNodeId.value = String(row.originId)
  } else if (row.type === 'dept') {
    // message.error("请选择设备及文件节点")
    // return
  }
  nodeId.value = String(row.id)
  await getList()
}

// 面包屑点击事件
const handleBreadcrumbClick = async (index: number) => {
  queryParams.filename = ''
  // 忽略当前节点的点击
  if (index === breadcrumbs.value.length - 1) return

  formLoading.value = true

  // 截断面包屑到点击的节点
  const targetBreadcrumbs = breadcrumbs.value.slice(0, index + 1)
  breadcrumbs.value = targetBreadcrumbs

  // 获取对应节点的数据
  let targetId = targetBreadcrumbs[index].id
  if (!targetId) {
    targetId = topNodeId.value
  }
  if (!targetId) {
    formLoading.value = false
    return
  }

  queryParams.classId = targetId
  clickNodeId.value = String(targetId)
  nodeId.value = String(targetId)
  const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
  list.value = data
  formLoading.value = false
}

/** 查询列表 */
const getList = async () => {
  formLoading.value = true
  try {
    const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
    list.value = data
  } finally {
    formLoading.value = false
  }
}
/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

/** 初始化 */
onMounted(async () => {
  id.value = Number(params.id) || 0
})
</script>
<style scoped>
:deep(.el-form-item) {
  margin-bottom: 0;
}

:deep(.search-panel .el-form-item) {
  display: flex;
  align-items: center;
}

:deep(.search-panel .el-form-item__label) {
  height: 32px;
  line-height: 32px;
  align-items: center;
}

:deep(.search-panel .el-form-item__content) {
  display: flex;
  align-items: center;
}

.tree-page {
  min-width: 0;
}

.search-panel,
.breadcrumb-panel,
.table-panel {
  min-width: 0;
}

:deep(.breadcrumb-container) {
  min-width: 0;
  padding: 0;
  overflow: hidden;
}

:deep(.custom-breadcrumb-item) {
  font-size: 14px;
  font-weight: 600;
}

:deep(.el-breadcrumb__item .el-breadcrumb__inner) {
  padding: 2px 4px;
  color: #101010;
  text-decoration: none;
  border-radius: 2px;
  transition: all 0.2s ease;
}

:deep(.el-breadcrumb__item:not(:last-child) .el-breadcrumb__inner:hover) {
  color: #409eff;
  cursor: pointer;
  background-color: rgb(64 158 255 / 10%);
}

:deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) {
  font-weight: 500;
  color: #1890ff;
  cursor: default;
}

:deep(.el-breadcrumb__separator) {
  margin: 0 8px;
  font-size: 12px;
  color: #0954f6;
}

:deep(.zm-table) {
  height: 100%;

  .el-table__cell {
    height: 42px;
  }

  .el-table__row {
    cursor: pointer;
  }
}
</style>
