<script setup lang="ts">
import type { FilePreviewInitOptions } from './index.vue'
/**
 * 文件预览弹窗组件
 * 支持两种展示形式，通过 mode prop 控制：
 *  - drawer（默认）：从底部滑出的抽屉，占屏幕 92% 高度
 *  - dialog：居中弹窗，固定宽高
 *
 * 底部操作栏（仅通过此组件打开时显示）：
 *  - 下载
 *  - 用其他应用打开（仅 Flutter 环境，调用 openFileWithApp 方式二：传 url+name）
 *
 * 用法：
 *   <FilePreviewDialog ref="dialogRef" mode="dialog" @close="onClose" />
 *   dialogRef.value.open({ path: '/resource/...', name: '文件名.docx' })
 */
import { detectEnvironment } from '@af-mobile-client-vue3/utils/environment'
import { downloadAttachment, openFileWithApp } from '@af-mobile-client-vue3/utils/fileDownload'
import { Popup as VanPopup } from 'vant'
import { computed, ref } from 'vue'
import FilePreview from './index.vue'

const props = withDefaults(defineProps<{
  /** 展示形式：drawer 底部抽屉（默认）| dialog 居中弹窗 */
  mode?: 'drawer' | 'dialog'
}>(), {
  mode: 'drawer',
})

const emit = defineEmits<{
  (e: 'close'): void
}>()

const visible = ref(false)
const fileName = ref('')
const fileUrl = ref('')
const previewRef = ref<InstanceType<typeof FilePreview> | null>(null)
const initOptions = ref<FilePreviewInitOptions | null>(null)
const loadingKey = ref<string | null>(null) // 当前正在执行的操作 key，null 表示空闲

const isApp = computed(() => detectEnvironment().isApp)

/** 操作按钮配置，后续新增按钮只需在此追加 */
interface ActionItem {
  key: string
  label: string
  /** 仅在特定环境显示，不传则始终显示 */
  show?: () => boolean
  handler: () => Promise<void> | void
}

const actions = computed<ActionItem[]>(() => [
  {
    key: 'download',
    label: '下载',
    handler: handleDownload,
  },
  {
    key: 'openWithApp',
    label: '用其他应用打开',
    // 仅 Flutter App 环境显示
    show: () => isApp.value,
    handler: handleOpenWithApp,
  },
])

/** 过滤出当前环境应显示的按钮 */
const visibleActions = computed(() =>
  actions.value.filter(a => !a.show || a.show()),
)

function open(options: FilePreviewInitOptions) {
  fileName.value = options.name || options.path.split('/').pop()?.split('?')[0] || '文件预览'
  fileUrl.value = options.path
  initOptions.value = options
  visible.value = true
}

function onOpened() {
  if (initOptions.value)
    previewRef.value?.init(initOptions.value)
}

function handleClose() {
  visible.value = false
  emit('close')
}

/** 下载文件 */
async function handleDownload() {
  await downloadAttachment({ url: fileUrl.value, name: fileName.value })
}

/**
 * 用其他应用打开（方式二：传 url+name，Flutter 端自动下载后调起系统分享面板）
 */
function handleOpenWithApp() {
  openFileWithApp(fileUrl.value, fileName.value)
}

/** 执行操作按钮，防重复点击 */
async function runAction(action: ActionItem) {
  if (loadingKey.value)
    return
  loadingKey.value = action.key
  try {
    await action.handler()
  }
  finally {
    loadingKey.value = null
  }
}

defineExpose({ open })
</script>

<template>
  <VanPopup
    v-model:show="visible"
    :position="mode === 'drawer' ? 'bottom' : 'center'"
    :style="mode === 'drawer'
      ? { height: '92vh' }
      : { width: '90vw', height: '80vh', borderRadius: '12px' }"
    :round="mode === 'drawer'"
    @opened="onOpened"
  >
    <div class="dialog-root">
      <!-- 顶部标题栏 -->
      <div class="dialog-header" :class="{ 'dialog-header--center': mode === 'dialog' }">
        <span class="dialog-title" :title="fileName">{{ fileName }}</span>
        <button class="dialog-close" @click="handleClose">
          ✕
        </button>
      </div>

      <!-- 预览区域 -->
      <div class="dialog-body">
        <FilePreview ref="previewRef" class="dialog-preview" />
      </div>

      <!-- 底部操作栏 -->
      <div class="dialog-actions">
        <button
          v-for="action in visibleActions"
          :key="action.key"
          class="action-btn"
          :class="`action-btn--${action.key}`"
          :disabled="!!loadingKey"
          @pointerdown.stop="runAction(action)"
        >
          {{ loadingKey === action.key ? '处理中...' : action.label }}
        </button>
      </div>
    </div>
  </VanPopup>
</template>

<style scoped>
.dialog-root {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  height: 48px;
  background: #1677ff;
  flex-shrink: 0;
  border-radius: 16px 16px 0 0;
}

.dialog-header--center {
  border-radius: 12px 12px 0 0;
}

.dialog-title {
  flex: 1;
  font-size: 16px;
  font-weight: 500;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-right: 12px;
}

.dialog-close {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}

.dialog-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.dialog-preview {
  flex: 1;
  height: 100%;
}

/* 底部操作栏：按钮数量自适应 */
.dialog-actions {
  display: flex;
  gap: 10px;
  padding: 10px 16px;
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid #f0f0f0;
  flex-shrink: 0;
  background: #fff;
}

.action-btn {
  flex: 1;
  height: 40px;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
  transition: opacity 0.15s;
}

.action-btn:disabled {
  opacity: 0.5;
}

/* 下载：主色蓝 */
.action-btn--download {
  background: #1677ff;
  color: #fff;
}

/* 用其他应用打开：次级灰白 */
.action-btn--openWithApp {
  background: #f5f5f5;
  color: #333;
  border: 1px solid #e0e0e0;
}
</style>
