<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { api, type BrowseDirectoryResponse, type FileRecordDto, type LibraryRootDto, type TextPreviewDto } from '../api'
import QrCodeModal from './QrCodeModal.vue'

const roots = ref<LibraryRootDto[]>([])
const browseData = ref<BrowseDirectoryResponse | null>(null)
const selectedFile = ref<FileRecordDto | null>(null)
const textPreview = ref<TextPreviewDto | null>(null)
const loading = ref(false)
const errorMessage = ref('')

// Navigation state
const rootId = ref<number | undefined>()
const browsePath = ref<string[]>([])
const isBrowsingRoots = ref(true)

const qrModal = ref<InstanceType<typeof QrCodeModal> | null>(null)

const activeRoots = computed(() => roots.value.filter((root) => root.isEnabled && root.isAvailable))
const selectedRoot = computed(() => roots.value.find((root) => root.id === selectedFile.value?.libraryRootId))
const currentBrowsePath = computed(() => browsePath.value.join('/'))

const breadcrumbs = computed(() => {
  const root = roots.value.find((r) => r.id === rootId.value)
  const items = [{ label: root?.displayName ?? '文件库', path: '' }]
  for (let i = 0; i < browsePath.value.length; i++) {
    items.push({
      label: browsePath.value[i],
      path: browsePath.value.slice(0, i + 1).join('/'),
    })
  }
  return items
})

const selectedMediaUrl = computed(() => selectedFile.value ? api.mediaUrl(selectedFile.value.streamUrl) : '')

const clientTitle = computed(() => {
  if (isBrowsingRoots.value) return '文件库'
  const root = roots.value.find((r) => r.id === rootId.value)
  const dir = browsePath.value.length > 0 ? browsePath.value[browsePath.value.length - 1] : ''
  return dir || (root?.displayName ?? '文件')
})

function formatSize(bytes: number) {
  if (bytes < 1024) return `${bytes} B`
  const units = ['KB', 'MB', 'GB', 'TB']
  let value = bytes / 1024
  let index = 0
  while (value >= 1024 && index < units.length - 1) {
    value /= 1024
    index += 1
  }
  return `${value.toFixed(value >= 10 ? 1 : 2)} ${units[index]}`
}

function formatDate(value: string | null) {
  if (!value) return ''
  return new Date(value).toLocaleString()
}

function setError(error: unknown) {
  errorMessage.value = error instanceof Error ? error.message : '操作失败'
}

async function loadRoots() {
  roots.value = await api.getRoots()
}

async function browseDirectory() {
  if (!rootId.value) return
  try {
    errorMessage.value = ''
    loading.value = true
    browseData.value = await api.browseDirectory(rootId.value, currentBrowsePath.value)
  } catch (error) {
    setError(error)
  } finally {
    loading.value = false
  }
}

async function enterRoot(id: number) {
  rootId.value = id
  isBrowsingRoots.value = false
  browsePath.value = []
  selectedFile.value = null
  textPreview.value = null
  await browseDirectory()
}

function backToRoots() {
  isBrowsingRoots.value = true
  rootId.value = undefined
  browseData.value = null
  browsePath.value = []
  selectedFile.value = null
  textPreview.value = null
}

async function navigateTo(path: string) {
  if (path === '') {
    browsePath.value = []
  } else {
    browsePath.value = path.split('/')
  }
  selectedFile.value = null
  textPreview.value = null
  await browseDirectory()
}

async function enterSubdirectory(name: string) {
  browsePath.value.push(name)
  selectedFile.value = null
  textPreview.value = null
  await browseDirectory()
}

async function selectFile(file: FileRecordDto) {
  selectedFile.value = file
  textPreview.value = null
  if (file.mediaType !== 'text') return

  try {
    textPreview.value = await api.getTextPreview(file.id)
  } catch (error) {
    setError(error)
  }
}

onMounted(async () => {
  loading.value = true
  try {
    await loadRoots()
  } catch (error) {
    setError(error)
  } finally {
    loading.value = false
  }
})
</script>

<template>
  <main class="client-shell">
    <header class="mobile-header">
      <div>
        <h1>{{ clientTitle }}</h1>
        <p>
          <template v-if="isBrowsingRoots">{{ activeRoots.length }} 个目录</template>
          <template v-else-if="browseData">
            {{ browseData.subdirectories.length }} 个文件夹 · {{ browseData.files.length }} 个文件
          </template>
        </p>
      </div>
      <div class="mobile-header-actions">
        <button v-if="!isBrowsingRoots" type="button" class="back-button" @click="backToRoots">返回</button>
        <button type="button" class="qr-button" title="生成二维码" @click="qrModal?.open()">二维码</button>
        <a href="/admin" class="admin-link">管理</a>
      </div>
    </header>

    <p v-if="errorMessage" class="error-banner">{{ errorMessage }}</p>

    <!-- Library root tiles -->
    <section v-if="isBrowsingRoots" class="root-picker">
      <button
        v-for="root in activeRoots"
        :key="root.id"
        class="root-tile"
        type="button"
        @click="enterRoot(root.id)"
      >
        <span>{{ root.displayName }}</span>
        <strong>{{ root.fileCount }}</strong>
        <small>{{ root.path }}</small>
      </button>
      <p v-if="activeRoots.length === 0" class="empty-state">暂无可访问目录</p>
    </section>

    <!-- Directory browser -->
    <template v-else>
      <!-- Breadcrumb -->
      <nav class="breadcrumb-nav">
        <template v-for="(crumb, index) in breadcrumbs" :key="crumb.path">
          <span v-if="index > 0" class="breadcrumb-sep">/</span>
          <button
            type="button"
            class="breadcrumb-item"
            :class="{ active: index === breadcrumbs.length - 1 }"
            @click="navigateTo(crumb.path)"
          >
            {{ crumb.label }}
          </button>
        </template>
      </nav>

      <section v-if="browseData" class="browse-content">
        <!-- Subdirectories -->
        <section v-if="browseData.subdirectories.length > 0" class="browse-section">
          <h3>文件夹</h3>
          <div class="folder-grid">
            <button
              v-for="dir in browseData.subdirectories"
              :key="dir"
              type="button"
              class="folder-item"
              @click="enterSubdirectory(dir)"
            >
              <span class="folder-icon">&#128193;</span>
              <span>{{ dir }}</span>
            </button>
          </div>
        </section>

        <!-- Media player -->
        <section v-if="selectedFile" class="player-panel">
          <div class="player-title">
            <div>
              <h2>{{ selectedFile.fileName }}</h2>
              <p>{{ selectedRoot?.displayName ?? '文件库' }} · {{ selectedFile.relativePath }}</p>
            </div>
            <span>{{ selectedFile.extension }}</span>
          </div>

          <video
            v-if="selectedFile.mediaType === 'video' && selectedFile.browserPlayable"
            :key="selectedFile.id"
            controls
            playsinline
            webkit-playsinline
            preload="metadata"
          >
            <source :src="selectedMediaUrl" :type="selectedFile.contentType" />
          </video>
          <audio
            v-else-if="selectedFile.mediaType === 'audio' && selectedFile.browserPlayable"
            :key="selectedFile.id"
            controls
            preload="metadata"
          >
            <source :src="selectedMediaUrl" :type="selectedFile.contentType" />
          </audio>
          <pre v-else-if="selectedFile.mediaType === 'text'">{{ textPreview?.content ?? '加载中...' }}</pre>
          <p v-else class="unsupported">浏览器不支持在线播放此格式。</p>
          <a
            v-if="selectedFile.mediaType !== 'text'"
            class="open-media-link"
            :href="selectedMediaUrl"
            target="_blank"
            rel="noreferrer"
          >
            新窗口打开原视频/音频
          </a>
          <p v-if="textPreview?.truncated" class="hint">文本超过 1 MB，已截断显示。</p>
        </section>

        <!-- Files -->
        <section v-if="browseData.files.length > 0" class="browse-section">
          <h3>文件</h3>
          <div class="file-list">
            <button
              v-for="file in browseData.files"
              :key="file.id"
              class="mobile-file"
              :class="{ active: selectedFile?.id === file.id }"
              type="button"
              @click="selectFile(file)"
            >
              <span class="type-badge">{{ file.mediaType }}</span>
              <span>
                <strong>{{ file.fileName }}</strong>
                <small>{{ formatSize(file.sizeBytes) }} · {{ formatDate(file.lastWriteTimeUtc) }}</small>
              </span>
            </button>
          </div>
        </section>

        <p v-if="browseData.subdirectories.length === 0 && browseData.files.length === 0" class="empty-state">
          此目录下没有支持的文件
        </p>
      </section>

      <p v-else-if="!loading" class="empty-state">加载中...</p>
    </template>
  </main>

  <QrCodeModal ref="qrModal" />
</template>
