<!-- File详情页工具栏组件 -->
<template>
  <n-space align="center">
    <!-- 上一条 -->
    <n-button
      type="default"
      size="medium"
      @click="goToPrev"
      :disabled="context.loading || fetching || !hasPrev"
      :title="context.t('Previous')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:chevron-left" /></n-icon>
      </template>
    </n-button>

    <!-- 下一条 -->
    <n-button
      type="default"
      size="medium"
      @click="goToNext"
      :disabled="context.loading || fetching || !hasNext"
      :title="context.t('Next')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:chevron-right" /></n-icon>
      </template>
    </n-button>

    <!-- 返回列表 -->
    <n-button type="default" size="medium" @click="goBack" :disabled="context.loading" :title="context.t('Back')">
      <template #icon>
        <n-icon><Icon icon="tabler:arrow-left" /></n-icon>
      </template>
    </n-button>

    <!-- 刷新 -->
    <n-button
      type="default"
      size="medium"
      @click="context.refresh"
      :disabled="context.loading"
      :title="context.t('Refresh')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:refresh" /></n-icon>
      </template>
    </n-button>

    <n-divider vertical />

    <!-- File 专属操作 -->
    <n-button type="default" size="medium" @click="viewFile" v-if="context.record.file_url">
      <template #icon>
        <n-icon><Icon icon="tabler:eye" /></n-icon>
      </template>
      {{ context.t('View File') }}
    </n-button>

    <n-button type="default" size="medium" @click="downloadFile" v-if="context.record.file_url && !context.record.is_folder">
      <template #icon>
        <n-icon><Icon icon="tabler:download" /></n-icon>
      </template>
      {{ context.t('Download') }}
    </n-button>

    <n-button type="default" size="medium" :disabled="optimizing" :loading="optimizing" @click="optimizeFile" v-if="isOptimizable">
      <template #icon>
        <n-icon><Icon icon="tabler:photo-spark" /></n-icon>
      </template>
      {{ context.t('Optimize') }}
    </n-button>

    <n-button type="default" size="medium" :disabled="unzipping" :loading="unzipping" @click="unzipFile" v-if="isZipFile">
      <template #icon>
        <n-icon><Icon icon="tabler:archive" /></n-icon>
      </template>
      {{ context.t('Unzip') }}
    </n-button>

    <!-- 保存按钮 -->
    <n-button
      type="primary"
      size="medium"
      :disabled="context.loading"
      @click="context.save"
      v-if="context.canEdit"
      class="save-btn-brand"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:check" /></n-icon>
      </template>
      {{ context.t('Save') }}
    </n-button>
  </n-space>
</template>

<script setup lang="ts">
import { computed, ref, onMounted } from 'vue'
import { NButton, NSpace, NIcon, NDivider, useMessage } from 'naive-ui'
import { Icon } from '@iconify/vue'
import { api, getRecords } from '@/shared/api/common'
import { usePageTypeSlug } from '@/shared/utils/slug'
import { useRoute, useRouter } from 'vue-router'

const props = defineProps<{
  context: {
    entity: string
    id: string
    record: any
    canEdit: boolean
    loading: boolean
    save: () => Promise<void>
    refresh: () => Promise<void>
    router: any
    t: (key: string) => string
  }
}>()

const message = useMessage()
const route = useRoute()
const router = useRouter()
const { pagetypeSlug } = usePageTypeSlug(route)

const optimizing = ref(false)
const unzipping = ref(false)

// ===== 导航逻辑（对齐 DefaultToolbar，自动跳过文件夹） =====
const listStateKey = computed(() => `list-state:${props.context.entity}`)
const rowNames = ref<string[]>([])
const fetching = ref(false)
const loadedStart = ref(0)
const hasMoreNext = ref(false)
const hasMorePrev = ref(false)
const pageSize = parseInt(localStorage.getItem('itemsPerPage') || '10')

const currentIndex = computed(() => {
  if (!props.context.id || rowNames.value.length === 0) return -1
  return rowNames.value.indexOf(props.context.id)
})

const hasPrev = computed(() => {
  if (currentIndex.value < 0) return false
  // 向前找非文件夹记录
  for (let i = currentIndex.value - 1; i >= 0; i--) {
    if (!isFolderRow(rowNames.value[i])) return true
  }
  return hasMorePrev.value
})

const hasNext = computed(() => {
  if (currentIndex.value < 0) return false
  // 向后找非文件夹记录
  for (let i = currentIndex.value + 1; i < rowNames.value.length; i++) {
    if (!isFolderRow(rowNames.value[i])) return true
  }
  return hasMoreNext.value
})

// 缓存：name → is_folder 映射（从列表状态中获取）
const folderCache = ref<Record<string, boolean>>({})

function isFolderRow(name: string): boolean {
  return !!folderCache.value[name]
}

function readListState(): any | null {
  const saved = sessionStorage.getItem(listStateKey.value)
  if (!saved) return null
  try { return JSON.parse(saved) } catch { return null }
}

function loadRowNames() {
  const state = readListState()
  if (!state?.rowNames?.length) return
  rowNames.value = state.rowNames
  loadedStart.value = ((state.page || 1) - 1) * pageSize
  hasMorePrev.value = loadedStart.value > 0
  hasMoreNext.value = state.rowNames.length >= pageSize
  // 加载文件夹缓存
  if (state.folderMap) {
    folderCache.value = state.folderMap
  }
}

function navigateTo(name: string) {
  router.push({
    name: 'PageTypeDetail',
    params: { entity: pagetypeSlug.value, id: name },
  })
}

// 找到下一个非文件夹的索引
function findPrevNonFolder(): number {
  for (let i = currentIndex.value - 1; i >= 0; i--) {
    if (!isFolderRow(rowNames.value[i])) return i
  }
  return -1
}

function findNextNonFolder(): number {
  for (let i = currentIndex.value + 1; i < rowNames.value.length; i++) {
    if (!isFolderRow(rowNames.value[i])) return i
  }
  return -1
}

async function goToPrev() {
  if (fetching.value) return
  const idx = findPrevNonFolder()
  if (idx >= 0) {
    navigateTo(rowNames.value[idx])
  } else if (hasMorePrev.value) {
    fetching.value = true
    try {
      const state = readListState()
      if (!state) return
      const orderBy = `${state.sortBy || 'modified'} ${state.sortOrder || 'desc'}`
      const limitLength = Math.min(pageSize, loadedStart.value)
      const limitStart = loadedStart.value - limitLength
      if (limitLength <= 0) return
      const res = await getRecords(props.context.entity, [], ['name', 'is_folder'], orderBy, limitStart, limitLength)
      if (res.success && res.data?.length) {
        const newNames = res.data.map((r: any) => r.name)
        // 更新文件夹缓存
        res.data.forEach((r: any) => { folderCache.value[r.name] = !!r.is_folder })
        rowNames.value = [...newNames, ...rowNames.value]
        loadedStart.value -= newNames.length
        hasMorePrev.value = loadedStart.value > 0
        // 重新查找
        const newIdx = findPrevNonFolder()
        if (newIdx >= 0) navigateTo(rowNames.value[newIdx])
      }
    } finally { fetching.value = false }
  }
}

async function goToNext() {
  if (fetching.value) return
  const idx = findNextNonFolder()
  if (idx >= 0) {
    navigateTo(rowNames.value[idx])
  } else if (hasMoreNext.value) {
    fetching.value = true
    try {
      const state = readListState()
      if (!state) return
      const orderBy = `${state.sortBy || 'modified'} ${state.sortOrder || 'desc'}`
      const limitStart = loadedStart.value + rowNames.value.length
      const res = await getRecords(props.context.entity, [], ['name', 'is_folder'], orderBy, limitStart, pageSize)
      if (res.success && res.data?.length) {
        const newNames = res.data.map((r: any) => r.name)
        res.data.forEach((r: any) => { folderCache.value[r.name] = !!r.is_folder })
        rowNames.value = [...rowNames.value, ...newNames]
        hasMoreNext.value = newNames.length >= pageSize
        const newIdx = findNextNonFolder()
        if (newIdx >= 0) navigateTo(rowNames.value[newIdx])
      }
    } finally { fetching.value = false }
  }
}

function goBack() {
  router.push({
    name: 'PageTypeList',
    params: { entity: pagetypeSlug.value },
  })
}

onMounted(() => {
  loadRowNames()
})

// ===== File 专属操作 =====
const isOptimizable = computed(() => {
  const record = props.context.record
  if (record.is_folder || !record.file_size || record.file_size <= 0) return false
  const isRasterImage = /\.(gif|jpg|jpeg|tiff|png)$/i.test(record.file_url)
  return isRasterImage
})

const isZipFile = computed(() => {
  const record = props.context.record
  return record.file_name && record.file_name.split('.').pop() === 'zip'
})

function viewFile() {
  const record = props.context.record
  if (!record.file_url) return
  if (record.file_url.startsWith('http')) {
    window.open(record.file_url)
  } else {
    window.open(window.location.origin + record.file_url)
  }
}

function downloadFile() {
  const record = props.context.record
  if (!record.file_url) return
  let fileUrl = record.file_url
  if (record.file_name) {
    fileUrl = fileUrl.replace(/#/g, '%23')
  }
  window.open(fileUrl)
}

async function optimizeFile() {
  if (optimizing.value) return
  optimizing.value = true
  const record = props.context.record
  message.loading(props.context.t('Optimizing image...'), { duration: 0 })
  try {
    await api.call('run_pg_method', {
      dt: 'File',
      dn: record.name,
      method: 'optimize_file'
    })
    message.destroyAll()
    message.success(props.context.t('Image optimized'))
    await props.context.refresh()
  } catch (error: any) {
    message.destroyAll()
    message.error(error?.message || props.context.t('Optimization failed'))
  } finally {
    optimizing.value = false
  }
}

async function unzipFile() {
  if (unzipping.value) return
  unzipping.value = true
  const record = props.context.record
  message.loading(props.context.t('Unzipping file...'), { duration: 0 })
  try {
    await api.call('jingrow.core.api.file.unzip_file', { name: record.name })
    message.destroyAll()
    message.success(props.context.t('File unzipped successfully'))
    props.context.router.push({ name: 'PageTypeList', params: { entity: 'file' } })
  } catch (error: any) {
    message.destroyAll()
    message.error(error?.message || props.context.t('Unzip failed'))
  } finally {
    unzipping.value = false
  }
}
</script>

<style scoped>
/* 保存按钮 - 使用柔和的品牌色系 */
.save-btn-brand {
  background: #e6f8f0 !important;
  border: 1px solid #1fc76f !important;
  color: #0d684b !important;
}

.save-btn-brand :deep(.n-button__border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand:hover {
  background: #dcfce7 !important;
  border-color: #1fc76f !important;
  border: 1px solid #1fc76f !important;
  color: #166534 !important;
  box-shadow: 0 2px 8px rgba(31, 199, 111, 0.15) !important;
}

.save-btn-brand:hover :deep(.n-button__border),
.save-btn-brand:hover :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand:disabled {
  background: #f1f5f9 !important;
  border: 1px solid #e2e8f0 !important;
  color: #94a3b8 !important;
  opacity: 0.6 !important;
  cursor: not-allowed !important;
}

.save-btn-brand:disabled :deep(.n-button__border),
.save-btn-brand:disabled :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}
</style>
