<template>
  <div class="device-file-library">
    <section class="library-workbench">
      <div class="library-workbench__header">
        <div class="workbench-title">
          <span class="workbench-title__icon">
            <Icon icon="ep:files" />
          </span>
          <div>
            <h3>资料列表</h3>
            <p>{{ currentFolderName }} · {{ fileList.length }} 项</p>
          </div>
        </div>
        <el-form ref="queryFormRef" :model="queryParams" inline class="library-search-form">
          <el-form-item prop="filename">
            <el-input
              v-model="queryParams.filename"
              class="library-search-input"
              clearable
              size="default"
              placeholder="请输入文件名称"
              @keyup.enter="handleQuery">
              <template #prefix>
                <Icon icon="ep:search" />
              </template>
            </el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="default" @click="handleQuery">
              <Icon icon="ep:search" />
              搜索
            </el-button>
            <el-button size="default" @click="resetQuery">
              <Icon icon="ep:refresh" />
              重置
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <ZmTable
        :data="fileList"
        class="library-table"
        :loading="loading"
        :show-border="true"
        :column-max-width="420"
        row-key="id"
        empty-text="暂无数据"
        @row-dblclick="handleRowDblClick">
        <ZmTableColumn label="文件名称" prop="filename" min-width="320" align="left">
          <template #default="{ row }">
            <div class="file-name-cell">
              <span :class="['file-icon', `file-icon--${getFileIconType(row)}`]">
                <Icon :icon="getFileIcon(row)" />
              </span>
              <div class="file-name-cell__text">
                <strong>{{ row.filename || '-' }}</strong>
                <span v-if="row.fileType === 'content'">双击进入文件夹</span>
                <span v-else>{{ row.fileClassify || 'file' }}</span>
              </div>
            </div>
          </template>
        </ZmTableColumn>
        <ZmTableColumn label="文件类型" prop="fileType" min-width="120">
          <template #default="{ row }">
            <el-tag v-if="row.fileType === 'content'" type="warning" effect="light">文件夹</el-tag>
            <el-tag v-else type="info" effect="light">{{ row.fileClassify || '文件' }}</el-tag>
          </template>
        </ZmTableColumn>
        <ZmTableColumn label="文件大小" prop="fileSize" min-width="120">
          <template #default="{ row }">
            {{ row.fileSize || '-' }}
          </template>
        </ZmTableColumn>
        <ZmTableColumn label="所在部门" prop="deptName" min-width="160">
          <template #default="{ row }">
            {{ row.deptName || '-' }}
          </template>
        </ZmTableColumn>
        <ZmTableColumn label="所属设备" prop="deviceCode" min-width="180">
          <template #default="{ row }">
            {{ row.deviceCode || '-' }}
          </template>
        </ZmTableColumn>
        <ZmTableColumn label="操作" width="150" fixed="right" align="center" action>
          <template #default="{ row }">
            <div v-if="row.fileType !== 'content'" class="table-actions">
              <el-button
                link
                type="primary"
                size="default"
                class="table-action-btn"
                @click.stop="previewFile(row)">
                <Icon icon="ep:view" />
                预览
              </el-button>
              <el-button
                link
                type="primary"
                size="default"
                class="table-action-btn"
                @click.stop="downloadFile(row)">
                <Icon icon="ep:download" />
                下载
              </el-button>
            </div>
            <span v-else class="folder-action-tip">双击进入</span>
          </template>
        </ZmTableColumn>
      </ZmTable>
    </section>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import { Base64 } from 'js-base64'
import { IotInfoApi } from '@/api/pms/iotinfo'
import { IotTreeApi } from '@/api/system/tree'
import { useTableComponents } from '@/components/ZmTable/useTableComponents'

defineOptions({ name: 'DeviceFileLibrary' })

interface FileRecord {
  id?: number | string
  filename?: string
  name?: string
  fileType?: string
  fileClassify?: string
  filePath?: string
  fileSize?: string
  deptName?: string
  deviceCode?: string
}

interface BreadcrumbItem {
  id: number | string | null
  name: string
  key: string
}

const props = defineProps<{
  deviceId?: number
  deviceName?: string
}>()

const { ZmTable, ZmTableColumn } = useTableComponents<FileRecord>()
const queryFormRef = ref()
const loading = ref(false)
const fileList = ref<FileRecord[]>([])
const rootClassId = ref<number | string | null>(null)

const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  filename: '',
  fileType: null as string | null,
  createTime: [] as string[],
  deviceId: null as number | null,
  classId: null as number | string | null,
  deptId: undefined as number | undefined,
  allName: null as string | null
})

const rootName = computed(() => props.deviceName || '设备资料')
const breadcrumbs = ref<BreadcrumbItem[]>([{ id: null, name: '设备资料', key: 'root' }])
const currentFolderName = computed(() => {
  return breadcrumbs.value[breadcrumbs.value.length - 1]?.name || rootName.value
})

const resetBreadcrumbRoot = () => {
  breadcrumbs.value = [
    {
      id: rootClassId.value,
      name: rootName.value,
      key: String(rootClassId.value || 'root')
    }
  ]
}

const loadFiles = async () => {
  if (!queryParams.classId) return

  loading.value = true
  try {
    const data = await IotInfoApi.getChildContentFile(queryParams)
    fileList.value = Array.isArray(data) ? data : []
  } finally {
    loading.value = false
  }
}

const initLibrary = async () => {
  if (!props.deviceId) return

  loading.value = true
  try {
    const rootId = await IotTreeApi.getDeviceTree(props.deviceId)
    rootClassId.value = rootId
    queryParams.deviceId = props.deviceId
    queryParams.classId = rootId
    resetBreadcrumbRoot()
    await loadFiles()
  } finally {
    loading.value = false
  }
}

const handleQuery = () => {
  queryParams.pageNo = 1
  loadFiles()
}

const resetQuery = () => {
  queryFormRef.value?.resetFields()
  queryParams.filename = ''
  queryParams.pageNo = 1
  loadFiles()
}

const enterFolder = async (row: FileRecord) => {
  if (!row.id) return

  queryParams.filename = ''
  queryParams.classId = row.id
  breadcrumbs.value.push({
    id: row.id,
    name: row.filename || row.name || '未命名目录',
    key: String(row.id)
  })
  await loadFiles()
}

const handleRowDblClick = (row: FileRecord) => {
  if (row.fileType === 'content') {
    enterFolder(row)
    return
  }
  previewFile(row)
}

const previewFile = (row: FileRecord) => {
  if (!row.filePath) return

  const previewUrl =
    'http://doc.deepoil.cc:8012/onlinePreview?url=' +
    encodeURIComponent(Base64.encode(row.filePath))
  window.open(previewUrl)
}

const downloadFile = async (row: FileRecord) => {
  if (!row.filePath) return

  try {
    const response = await fetch(row.filePath)
    const blob = await response.blob()
    const downloadUrl = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = downloadUrl
    link.download = row.filename || row.filePath.split('/').pop() || 'download'
    link.click()
    URL.revokeObjectURL(downloadUrl)
  } catch {
    window.open(row.filePath)
  }
}

const getFileIconType = (row: FileRecord) => {
  if (row.fileType === 'content') return 'folder'
  const type = row.fileClassify?.toLowerCase()
  if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(type || '')) return 'image'
  if (type === 'pdf') return 'pdf'
  if (['doc', 'docx'].includes(type || '')) return 'word'
  if (['xls', 'xlsx'].includes(type || '')) return 'excel'
  if (['ppt', 'pptx'].includes(type || '')) return 'ppt'
  return 'file'
}

const getFileIcon = (row: FileRecord) => {
  const iconType = getFileIconType(row)
  const iconMap: Record<string, string> = {
    folder: 'fa:folder-open',
    image: 'ep:picture-filled',
    pdf: 'fa-solid:file-pdf',
    word: 'fa:file-word-o',
    excel: 'fa-solid:file-excel',
    ppt: 'fa-solid:file-powerpoint',
    file: 'fa-solid:file-alt'
  }
  return iconMap[iconType]
}

watch(
  () => [props.deviceId, props.deviceName],
  () => {
    initLibrary()
  },
  { immediate: true }
)
</script>

<style scoped lang="scss">
.device-file-library {
  display: grid;
  gap: 14px;
}

.library-workbench {
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
}

.library-workbench {
  padding: 14px;
  overflow: hidden;
  background: linear-gradient(180deg, #f8fbff 0, var(--el-bg-color) 96px), var(--el-bg-color);
}

.library-workbench__header {
  display: flex;
  gap: 16px;
  min-height: 56px;
  margin-bottom: 14px;
  align-items: center;
  justify-content: space-between;
}

.workbench-title {
  display: flex;
  gap: 12px;
  min-width: 0;
  align-items: center;

  h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    line-height: 24px;
    color: var(--el-text-color-primary);
  }

  p {
    margin: 2px 0 0;
    font-size: 12px;
    line-height: 18px;
    color: var(--el-text-color-secondary);
  }
}

.workbench-title__icon {
  display: flex;
  width: 38px;
  height: 38px;
  font-size: 18px;
  color: #3478f6;
  background: #eaf2ff;
  border-radius: 10px;
  flex: none;
  align-items: center;
  justify-content: center;
}

.library-search-form {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;

  :deep(.el-form-item) {
    margin-right: 10px;
    margin-bottom: 0;
  }

  :deep(.el-form-item:last-child) {
    margin-right: 0;
  }
}

.library-search-input {
  width: 260px;
}

.library-table {
  --el-table-header-bg-color: var(--el-fill-color-lighter);
  --el-table-row-hover-bg-color: #f6faff;

  overflow: hidden;
  border-radius: 8px;

  :deep(.el-table__cell) {
    padding: 9px 0;
  }

  :deep(.el-table__body .el-table__row) {
    height: 56px;
  }
}

.file-name-cell {
  display: flex;
  gap: 12px;
  min-width: 0;
  align-items: center;
}

.file-icon {
  display: flex;
  width: 38px;
  height: 38px;
  font-size: 16px;
  border-radius: 8px;
  flex: none;
  align-items: center;
  justify-content: center;
}

.file-icon--folder {
  color: #d08a00;
  background: #fff5df;
}

.file-icon--image {
  color: #2183d1;
  background: #e9f4ff;
}

.file-icon--pdf {
  color: #d93025;
  background: #fff0ef;
}

.file-icon--word {
  color: #2b65d9;
  background: #eef4ff;
}

.file-icon--excel {
  color: #107c41;
  background: #eaf8ef;
}

.file-icon--ppt {
  color: #c43e1c;
  background: #fff1eb;
}

.file-icon--file {
  color: var(--el-text-color-secondary);
  background: var(--el-fill-color-light);
}

.file-name-cell__text {
  min-width: 0;

  strong,
  span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  strong {
    font-size: 14px;
    font-weight: 600;
    line-height: 22px;
    color: var(--el-text-color-primary);
  }

  span {
    font-size: 12px;
    line-height: 18px;
    color: var(--el-text-color-secondary);
  }
}

.table-actions {
  display: flex;
  gap: 4px;
  align-items: center;
  justify-content: center;
}

.table-action-btn {
  :deep(.iconify) {
    margin-right: 4px;
  }
}

.folder-action-tip {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

@media (width <= 767px) {
  .library-workbench__header {
    align-items: stretch;
    flex-direction: column;
  }

  .library-search-form {
    justify-content: flex-start;
  }

  .library-search-input {
    width: 100%;
  }
}
</style>
