<script setup lang="ts">
import { computed, ref } from 'vue';

import { EasyFlowPanelModal } from '@easyflow/common-ui';

import { ElButton, ElEmpty, ElImage, ElScrollbar } from 'element-plus';

import { api } from '#/api/request';
import { $t } from '#/locales';

defineExpose({
  openDialog,
});
const dialogVisible = ref(false);
const data = ref<any>();
const docPreviewLoading = ref(false);
const docPreviewContent = ref('');
const docPreviewTruncated = ref(false);
const docPreviewError = ref('');
let previewRequestId = 0;

const isDocument = computed(() => data.value?.resourceType === 3);
const fileName = computed(() => {
  const resourceName = data.value?.resourceName || '';
  const suffix = data.value?.suffix || '';
  return suffix ? `${resourceName}.${suffix}` : resourceName;
});
const previewWidth = computed(() => (isDocument.value ? 'xl' : 'md'));

async function openDialog(row: any) {
  data.value = row;
  dialogVisible.value = true;
  resetDocumentPreview();
  if (row?.resourceType === 3) {
    await loadDocumentPreview(row);
  }
}
function closeDialog() {
  dialogVisible.value = false;
}

function resetDocumentPreview() {
  docPreviewLoading.value = false;
  docPreviewContent.value = '';
  docPreviewTruncated.value = false;
  docPreviewError.value = '';
}

async function loadDocumentPreview(row: any) {
  if (!row?.id) {
    docPreviewError.value = '当前素材缺少预览标识，请下载后查看';
    return;
  }
  const currentRequestId = ++previewRequestId;
  docPreviewLoading.value = true;
  try {
    const res = await api.get('/api/v1/resource/previewContent', {
      params: { id: row.id },
    });
    if (currentRequestId !== previewRequestId) {
      return;
    }
    docPreviewContent.value = res.data?.content || '';
    docPreviewTruncated.value = !!res.data?.truncated;
    if (!docPreviewContent.value) {
      docPreviewError.value = '暂未提取到可预览内容，请下载后查看';
    }
  } catch {
    if (currentRequestId !== previewRequestId) {
      return;
    }
    docPreviewError.value = '文档预览加载失败，请下载后查看';
  } finally {
    if (currentRequestId === previewRequestId) {
      docPreviewLoading.value = false;
    }
  }
}

function openSourceFile() {
  if (data.value?.resourceUrl) {
    window.open(data.value.resourceUrl, '_blank');
  }
}
</script>

<template>
  <EasyFlowPanelModal
    v-model:open="dialogVisible"
    :title="$t('message.preview')"
    :before-close="closeDialog"
    :width="previewWidth"
    :show-footer="false"
  >
    <div class="resource-preview flex justify-center">
      <ElImage
        v-if="data.resourceType === 0"
        style="width: 200px"
        :preview-src-list="[data.resourceUrl]"
        :src="data.resourceUrl"
      />
      <video
        v-else-if="data.resourceType === 1"
        controls
        width="640"
        height="360"
      >
        <source :src="data.resourceUrl" type="video/mp4" />
        {{ $t('message.notVideo') }}
      </video>
      <audio
        v-else-if="data.resourceType === 2"
        controls
        class="mt-8 w-full max-w-[640px]"
        :src="data.resourceUrl"
      >
        {{ $t('message.notAudio') }}
      </audio>
      <div
        v-else-if="isDocument"
        v-loading="docPreviewLoading"
        :element-loading-text="$t('message.loading')"
        class="resource-preview__document bg-background border-border w-full rounded-xl border"
      >
        <div
          class="resource-preview__toolbar border-border flex items-center justify-between gap-3 border-b px-5 py-4"
        >
          <div class="min-w-0">
            <div class="truncate text-sm font-medium">{{ fileName }}</div>
            <div
              v-if="docPreviewTruncated"
              class="text-muted-foreground mt-1 text-xs"
            >
              内容较长，当前仅展示前 20000 个字符
            </div>
          </div>
          <ElButton link type="primary" @click="openSourceFile">
            {{ $t('button.download') }}
          </ElButton>
        </div>
        <div class="resource-preview__body">
          <ElEmpty
            v-if="docPreviewError"
            :description="docPreviewError"
            class="resource-preview__empty"
          >
            <ElButton link type="primary" @click="openSourceFile">
              {{ $t('button.download') }}
            </ElButton>
          </ElEmpty>
          <ElScrollbar
            v-else
            class="resource-preview__scrollbar"
            wrap-class="resource-preview__scrollbar-wrap"
          >
            <pre class="resource-preview__content">{{
              docPreviewContent
            }}</pre>
          </ElScrollbar>
        </div>
      </div>
    </div>
  </EasyFlowPanelModal>
</template>

<style scoped>
.resource-preview {
  min-height: 220px;
}

.resource-preview__document {
  min-height: 540px;
  overflow: hidden;
}

.resource-preview__toolbar {
  min-height: 72px;
}

.resource-preview__body {
  height: 468px;
}

.resource-preview__scrollbar {
  height: 100%;
}

:deep(.resource-preview__scrollbar-wrap) {
  padding: 20px;
}

.resource-preview__content {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-family:
    'SFMono-Regular', 'JetBrains Mono', 'Fira Code', Consolas, 'Liberation Mono',
    monospace;
  font-size: 13px;
  line-height: 1.75;
  color: hsl(var(--foreground));
}

.resource-preview__empty {
  height: 100%;
}
</style>
