<template>
  <div
    class="min-h-screen flex items-center justify-center p-4 overflow-hidden transition-colors duration-300"
  >
    <div class="w-full max-w-md relative z-10">
      <div
        class="rounded-3xl shadow-2xl overflow-hidden border transform transition-all duration-300"
        :class="[
          isDarkMode
            ? 'bg-gray-800 bg-opacity-50 backdrop-filter backdrop-blur-xl border-gray-700'
            : 'bg-white border-gray-200'
        ]"
      >
        <div class="p-8">
          <PageHeader :title="config.name" @title-click="toSend" />
          <RetrieveForm
            :input-status="inputStatus"
            :error="!!error"
            @submit="handleSubmit"
            @update:code="code = $event"
            ref="retrieveFormRef"
          />
        </div>
        <PageFooter
          :link-text="$t('retrieve.needSendFile')"
          link-to="/send"
          :drawer-text="$t('retrieve.recordsDrawer')"
          @toggle-drawer="toggleDrawer"
        />
      </div>
    </div>

    <SideDrawer :visible="showDrawer" :title="$t('retrieve.recordsDrawer')" @close="toggleDrawer">
      <FileRecordList
        :records="records"
        @view-details="viewDetails"
        @download-record="downloadRecord"
        @delete-record="deleteRecord"
      />
    </SideDrawer>

    <FileDetailModal
      :visible="!!selectedRecord"
      :record="selectedRecord"
      @close="selectedRecord = null"
      @show-content-preview="showContentPreview"
      :get-download-url="getDownloadUrl"
      :get-qr-code-value="getQRCodeValue"
    />
    
    <ContentPreviewModal
      :visible="showPreview"
      :rendered-content="renderedContent"
      @close="showPreview = false"
      @copy-content="copyContent"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, inject, onMounted, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import PageHeader from '@/components/common/PageHeader.vue'
import RetrieveForm from '@/components/common/RetrieveForm.vue'
import PageFooter from '@/components/common/PageFooter.vue'
import SideDrawer from '@/components/common/SideDrawer.vue'
import FileDetailModal from '@/components/common/FileDetailModal.vue'
import FileRecordList from '@/components/common/FileRecordList.vue'
import ContentPreviewModal from '@/components/common/ContentPreviewModal.vue'

// 定义数据接口
interface FileRecord {
  id: number
  code: string
  filename: string
  size: string
  downloadUrl: string | null
  content: string | null
  date: string
}

interface InputStatus {
  readonly: boolean
  loading: boolean
}

import { useRouter, useRoute } from 'vue-router'
import { useFileDataStore } from '@/stores/fileData'
import { storeToRefs } from 'pinia'
import api from '@/utils/api'
import type { ApiResponse } from '@/types'

interface RetrieveResponse {
  code: string
  name: string
  text: string
  size: number
}
import { saveAs } from 'file-saver'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { useAlertStore } from '@/stores/alertStore'
import { copyToClipboard } from '@/utils/clipboard'

const { t } = useI18n()
const alertStore = useAlertStore()
const baseUrl = window.location.origin

const router = useRouter()
const isDarkMode = inject('isDarkMode')
const fileStore = useFileDataStore()
const { receiveData } = storeToRefs(fileStore)
const code = ref('')
const inputStatus = ref<InputStatus>({
  readonly: false,
  loading: false
})

const error = ref('')
const selectedRecord = ref<FileRecord | null>(null)
const showDrawer = ref(false)
const route = useRoute()

// 使用 receiveData 替代原来的 records
const records = receiveData
const config = JSON.parse(localStorage.getItem('config') || '{}')
const codeInput = ref<HTMLInputElement | null>(null)

onMounted(() => {
  if (codeInput.value) {
    codeInput.value.focus()
  }
  const query_code = route.query.code
  if (query_code && typeof query_code === 'string') {
    code.value = query_code
  }
})
watch(code, (newVal) => {
  if (newVal.length === 5) {
    handleSubmit()
  }
})

const getDownloadUrl = (record: FileRecord) => {
  if (record.downloadUrl) {
    if (record.downloadUrl.startsWith('http')) {
      return record.downloadUrl
    } else {
      return `${baseUrl}${record.downloadUrl}`
    }
  }
  return ''
}
// 在其他代码后添加复制功能
const copyContent = async () => {
  if (selectedRecord.value && selectedRecord.value.content) {
    await copyToClipboard(selectedRecord.value.content, {
      successMsg: t('fileRecord.contentCopied'),
      errorMsg: t('fileRecord.copyFailed')
    })
  }
}
const handleSubmit = async () => {
  if (code.value.length !== 5) {
    alertStore.showAlert(t('retrieve.messages.invalidCode'), 'error')
    return
  }

  inputStatus.value.readonly = true
  inputStatus.value.loading = true

  try {
    const response = await api.post('/share/select/', {
      code: code.value
    })
    const res = (response.data || response) as ApiResponse<RetrieveResponse>

    if (res && res.code === 200) {
      if (res.detail) {
        const isFile = res.detail.text.startsWith('/share/download') || res.detail.name !== 'Text'
        const newFileData = {
          id: Date.now(),
          code: res.detail.code,
          filename: res.detail.name,
          size: formatFileSize(res.detail.size),
          downloadUrl: isFile ? res.detail.text : null,
          content: isFile ? null : res.detail.text,
          date: new Date().toLocaleString()
        }
        let flag = true
        fileStore.receiveData.forEach((file: FileRecord) => {
          if (file.code === newFileData.code) {
            flag = false
          }
        })
        if (flag) {
          fileStore.addReceiveData(newFileData)
        }
        if (isFile) {
          selectedRecord.value = newFileData
        } else {
          selectedRecord.value = newFileData
          showPreview.value = true
        }
        alertStore.showAlert(t('retrieve.messages.retrieveSuccess'), 'success')
      } else {
        alertStore.showAlert(t('retrieve.messages.invalidCodeError'), 'error')
      }
    } else {
      alertStore.showAlert(t('retrieve.messages.retrieveFailure') + res.detail, 'error')
    }
  } catch (err: unknown) {
    console.error('Retrieve failed:', err)
    const error = err as { response?: { data?: { detail?: string } }; message?: string }
    const errorMessage = error?.response?.data?.detail || error?.message || t('retrieve.messages.unknownError')
    alertStore.showAlert(t('retrieve.messages.networkError') + errorMessage, 'error')
  } finally {
    inputStatus.value.readonly = false
    inputStatus.value.loading = false
    code.value = ''
  }
}

const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 ' + t('fileSize.bytes')
  const k = 1024
  const sizes = [t('fileSize.bytes'), t('fileSize.kb'), t('fileSize.mb'), t('fileSize.gb'), t('fileSize.tb')]
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const viewDetails = (record: FileRecord) => {
  selectedRecord.value = record
}

const deleteRecord = (id: number) => {
  const index = records.value.findIndex((record: FileRecord) => record.id === id)
  if (index !== -1) {
    fileStore.deleteReceiveData(index)
  }
}

const toggleDrawer = () => {
  showDrawer.value = !showDrawer.value
}

const toSend = () => {
  router.push('/send')
}

const getQRCodeValue = (record: FileRecord) => {
  if (record.downloadUrl) {
    return `${baseUrl}${record.downloadUrl}`
  } else {
    return `${baseUrl}?code=${record.code}`
  }
}

const downloadRecord = (record: FileRecord) => {
  if (record.downloadUrl) {
    // 如果是文件,直接下载
    window.open(
      `${record.downloadUrl.startsWith('http') ? '' : baseUrl}${record.downloadUrl}`,
      '_blank'
    )
  } else if (record.content) {
    // 如果是文本,转成txt下载
    const blob = new Blob([record.content], { type: 'text/plain;charset=utf-8' })
    saveAs(blob, `${record.filename}.txt`)
  }
}

const showPreview = ref(false)
const renderedContent = ref('')

// 监听selectedRecord变化，异步渲染内容
watch(
  () => selectedRecord.value?.content,
  async (content) => {
    if (content) {
      try {
        // 使用 marked 解析 Markdown，然后用 DOMPurify 清理 HTML 防止 XSS
        const rawHtml = await marked(content)
        renderedContent.value = DOMPurify.sanitize(rawHtml, {
          // 允许的标签和属性
          ALLOWED_TAGS: [
            'p',
            'br',
            'strong',
            'em',
            'u',
            'h1',
            'h2',
            'h3',
            'h4',
            'h5',
            'h6',
            'ul',
            'ol',
            'li',
            'blockquote',
            'code',
            'pre',
            'a',
            'img'
          ],
          ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'class'],
          // 禁用危险的协议
          ALLOWED_URI_REGEXP:
            /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.-]+(?:[^a-z+.-:]|$))/i
        })
      } catch (error) {
        console.error('Markdown 渲染失败:', error)
        renderedContent.value = content // fallback 到原始内容
      }
    } else {
      renderedContent.value = ''
    }
  },
  { immediate: true }
)

const showContentPreview = () => {
  showPreview.value = true
}
</script>

<style scoped>
@keyframes blob {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }

  25% {
    transform: translate(20px, -50px) scale(1.1);
  }

  50% {
    transform: translate(-20px, 20px) scale(0.9);
  }

  75% {
    transform: translate(50px, 50px) scale(1.05);
  }
}

@media (min-width: 640px) {
  .sm\:w-120 {
    width: 30rem;
    /* 480px */
  }
}

.animate-spin-slow {
  animation: spin 8s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.w-97-100 {
  width: 97%;
}

/* 添加 Markdown 样式 */
:deep(.prose) {
  text-align: left;
  word-wrap: break-word;
  overflow-wrap: break-word;
  word-break: break-word;
}

:deep(.prose h1),
:deep(.prose h2),
:deep(.prose h3),
:deep(.prose h4),
:deep(.prose h5),
:deep(.prose h6) {
  color: rgb(79, 70, 229);
  /* text-indigo-600 */
  word-wrap: break-word;
  overflow-wrap: break-word;
}

:deep(.prose p),
:deep(.prose div),
:deep(.prose span),
:deep(.prose code),
:deep(.prose pre) {
  word-wrap: break-word;
  overflow-wrap: break-word;
  word-break: break-word;
}

:deep(.prose pre) {
  white-space: pre-wrap;
  overflow-x: auto;
}

:deep(.prose code) {
  white-space: pre-wrap;
}

@media (prefers-color-scheme: dark) {
  :deep(.prose h1),
  :deep(.prose h2),
  :deep(.prose h3),
  :deep(.prose h4),
  :deep(.prose h5),
  :deep(.prose h6) {
    color: rgb(129, 140, 248);
    /* text-indigo-400 */
  }
}

/* 添加新的宽度类 */
@media (min-width: 640px) {
  .sm\:w-120 {
    width: 30rem;
    /* 480px */
  }
}

/* 自定义滚动条样式 */
.custom-scrollbar {
  scrollbar-width: thin;
  scrollbar-color: rgba(156, 163, 175, 0.3) rgba(243, 244, 246, 0.5);
}

.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: rgba(243, 244, 246, 0.5);
  border-radius: 3px;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
  border-radius: 3px;
  transition: background-color 0.3s;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background-color: rgba(156, 163, 175, 0.7);
}

/* 深色模式下的滚动条样式 */
:deep([class*='dark']) .custom-scrollbar {
  scrollbar-color: rgba(75, 85, 99, 0.5) rgba(31, 41, 55, 0.5);
}

:deep([class*='dark']) .custom-scrollbar::-webkit-scrollbar-track {
  background: rgba(31, 41, 55, 0.5);
}

:deep([class*='dark']) .custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: rgba(75, 85, 99, 0.5);
}

:deep([class*='dark']) .custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background-color: rgba(75, 85, 99, 0.7);
}

/* 确保滚动容器有背景色 */
.custom-scrollbar {
  background: inherit;
}

/* 文本换行相关样式 */
.break-words {
  word-wrap: break-word;
  overflow-wrap: break-word;
  word-break: break-word;
}

.overflow-wrap-anywhere {
  overflow-wrap: anywhere;
}
</style>
