<template>
  <ContentWrap>
    <div class="page-title">
      <span class="back-btn" @click="handleBack">&#8249;</span>
      项目资料
    </div>

    <div class="info-panel">
      <div class="info-panel-title">{{ projectInfo.projectTitle || '-' }}</div>
      <div class="info-panel-meta">
        <div class="meta-left">
          <span v-if="projectInfo.startTime || projectInfo.endTime" class="meta-tag">
            {{ projectInfo.startTime || '' }}{{ projectInfo.endTime ? ` - ${projectInfo.endTime}` : '' }}
          </span>
          <span class="meta-item">会中序号：{{ projectInfo.seqNo ?? '-' }}</span>
        </div>
        <div class="meta-right">所属会议：{{ projectInfo.meetingName || '-' }}</div>
      </div>
      <div class="info-panel-footer">
        <div class="info-footer-item">
          <span class="footer-label">议程分类</span>
          <span class="footer-value">{{ materialSummary.agendaType || projectInfo.agendaCategory || '-' }}</span>
        </div>
        <div class="info-footer-item">
          <span class="footer-label">报告人</span>
          <span class="footer-value">
            {{ projectInfo.reporter || '-' }}
            <em v-if="projectInfo.reporterUnit">{{ projectInfo.reporterUnit }}</em>
          </span>
        </div>
        <div class="info-footer-item">
          <span class="footer-label">主持人</span>
          <span class="footer-value">{{ projectInfo.meetingHost || '-' }}</span>
        </div>
      </div>
    </div>

    <div class="material-card" v-loading="loading">
      <div class="material-toolbar">
        <div class="toolbar-title">上传资料</div>
        <el-button link type="primary" @click="handleDownloadTemplate">下载模板</el-button>
      </div>

      <div class="group-title">会前资料</div>
      <el-table :data="beforeMeetingMaterials" border class="material-table" empty-text="暂无会前资料">
        <el-table-column label="资料类型" min-width="220">
          <template #default="{ row }">
            <span>
              {{ row.materialName }}
              <span v-if="row.required" class="required-flag">*</span>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="资料文件" min-width="300">
          <template #default="{ row }">
            <span v-if="row.latestFile" class="file-name">{{ row.latestFile.fileName }}</span>
            <span v-else class="file-empty">未上传</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="260" align="center">
          <template #default="{ row }">
            <a class="op-link" @click="triggerUpload(row)">{{ row.latestFile ? '替换' : '上传' }}</a>
            <a class="op-link" :class="{ disabled: !row.latestFile }" @click="row.latestFile && handleDownload(row.latestFile)">下载</a>
            <a class="op-link" @click="openHistory(row)">历史版本</a>
          </template>
        </el-table-column>
      </el-table>

      <div class="group-title group-after">会后资料</div>
      <el-table :data="afterMeetingMaterials" border class="material-table" empty-text="暂无会后资料">
        <el-table-column label="资料类型" min-width="220">
          <template #default="{ row }">
            <span>
              {{ row.materialName }}
              <span v-if="row.required" class="required-flag">*</span>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="资料文件" min-width="300">
          <template #default="{ row }">
            <span v-if="row.latestFile" class="file-name">{{ row.latestFile.fileName }}</span>
            <span v-else class="file-empty">未上传</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="260" align="center">
          <template #default="{ row }">
            <a class="op-link" @click="triggerUpload(row)">{{ row.latestFile ? '替换' : '上传' }}</a>
            <a class="op-link" :class="{ disabled: !row.latestFile }" @click="row.latestFile && handleDownload(row.latestFile)">下载</a>
            <a class="op-link" @click="openHistory(row)">历史版本</a>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <input
      ref="uploadInputRef"
      type="file"
      class="hidden-upload-input"
      @change="handleFileSelected"
    />

    <el-dialog v-model="historyVisible" title="历史版本" width="760px">
      <el-table :data="historyList" border>
        <el-table-column label="版本" width="80" align="center">
          <template #default="{ row }">v{{ row.file.version || 1 }}</template>
        </el-table-column>
        <el-table-column label="文件名" prop="file.fileName" min-width="280" show-overflow-tooltip />
        <el-table-column label="上传人" prop="file.creator" width="120" align="center" />
        <el-table-column label="上传时间" prop="file.createTime" width="180" align="center" />
        <el-table-column label="操作" width="90" align="center">
          <template #default="{ row }">
            <a class="op-link" @click="handleDownload(row.file)">下载</a>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>

    <div class="form-footer">
      <button class="btn-default" @click="handleBack">返回</button>
    </div>
  </ContentWrap>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { getReviewMeeting } from '@/api/review/meeting'
import {
  downloadProjectTemplateBundle,
  getProjectMaterialHistory,
  getProjectMaterialSummary,
  uploadProjectMaterial,
  type ReviewMeetingFileRespVO,
  type ReviewMeetingMaterialHistoryRespVO,
  type ReviewMeetingMaterialItemRespVO,
  type ReviewMeetingMaterialSummaryRespVO
} from '@/api/review/project'

defineOptions({ name: 'ReviewProjectDetail' })

const route = useRoute()
const router = useRouter()

const reviewMeetingId = Number(route.params.meetingId)
const reviewMeetingProjectId = Number(route.params.projectId)

const state = window.history.state || {}
const projectInfo = ref({
  projectTitle: state.projectTitle as string | undefined,
  seqNo: state.seqNo as number | undefined,
  startTime: state.startTime as string | undefined,
  endTime: state.endTime as string | undefined,
  agendaCategory: state.agendaCategory as string | undefined,
  reporter: state.reporter as string | undefined,
  reporterUnit: state.reporterUnit as string | undefined,
  meetingHost: state.meetingHost as string | undefined,
  meetingName: state.meetingName as string | undefined
})

const loading = ref(false)
const materialSummary = ref<ReviewMeetingMaterialSummaryRespVO>({
  agendaType: '',
  templateAvailable: false,
  materials: []
})

const uploadInputRef = ref<HTMLInputElement>()
const uploadTarget = ref<ReviewMeetingMaterialItemRespVO>()

const historyVisible = ref(false)
const historyList = ref<ReviewMeetingMaterialHistoryRespVO[]>([])

const PHASE_MAPPING: Record<string, Record<string, 'before' | 'after'>> = {
  项目立项: {
    PROJECT_ARGUMENT_DOC: 'before',
    PROJECT_DEFENSE_PPT: 'before',
    PROJECT_EXPERT_OPINION_SIGNED: 'after'
  },
  预验收: {
    PRE_PROJECT_CONTRACT: 'before',
    PRE_REQUIREMENT_SPEC: 'before',
    PRE_ACCEPTANCE_REPORT: 'before',
    PRE_USER_FUNCTION_TEST: 'before',
    PRE_SERVICE_CHECKLIST: 'before'
  },
  项目终验: {
    FINAL_ACCEPTANCE_DOC: 'before',
    FINAL_DEFENSE_PPT: 'before',
    FINAL_DRAFT_EXPERT_OPINION: 'before',
    FINAL_SIGNED_EXPERT_OPINION: 'after',
    FINAL_RECTIFICATION_OPINION: 'after',
    FINAL_RECTIFICATION_REPLY: 'after'
  }
}

const beforeMeetingMaterials = computed(() => {
  const agendaType = materialSummary.value.agendaType
  const agendaMap = PHASE_MAPPING[agendaType] || {}
  return materialSummary.value.materials.filter((item) => agendaMap[item.materialCode] !== 'after')
})

const afterMeetingMaterials = computed(() => {
  const agendaType = materialSummary.value.agendaType
  const agendaMap = PHASE_MAPPING[agendaType] || {}
  return materialSummary.value.materials.filter((item) => agendaMap[item.materialCode] === 'after')
})

const loadSummary = async () => {
  loading.value = true
  try {
    materialSummary.value = await getProjectMaterialSummary(reviewMeetingProjectId)
  } finally {
    loading.value = false
  }
}

const handleDownloadTemplate = async () => {
  const agendaType = materialSummary.value.agendaType || projectInfo.value.agendaCategory
  if (!agendaType) {
    ElMessage.warning('未获取到议程分类')
    return
  }
  await downloadProjectTemplateBundle(agendaType)
}

const triggerUpload = (row: ReviewMeetingMaterialItemRespVO) => {
  uploadTarget.value = row
  if (!uploadInputRef.value) return
  uploadInputRef.value.value = ''
  uploadInputRef.value.accept = toAcceptAttr(row.acceptExts)
  uploadInputRef.value.click()
}

const handleFileSelected = async (event: Event) => {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  const target = uploadTarget.value
  if (!file || !target) return
  if (file.size > 500 * 1024 * 1024) {
    ElMessage.error('文件大小不能超过 500MB')
    return
  }
  if (!checkFileExt(file.name, target.acceptExts)) {
    ElMessage.error(`文件类型不合法，仅支持：${target.acceptExts}`)
    return
  }
  loading.value = true
  try {
    await uploadProjectMaterial(reviewMeetingId, reviewMeetingProjectId, target.materialCode, file)
    ElMessage.success('上传成功')
    await loadSummary()
  } catch {
    ElMessage.error('上传失败')
  } finally {
    loading.value = false
  }
}

const openHistory = async (row: ReviewMeetingMaterialItemRespVO) => {
  historyVisible.value = true
  historyList.value = []
  historyList.value = await getProjectMaterialHistory(reviewMeetingProjectId, row.materialCode)
}

const handleDownload = (file: ReviewMeetingFileRespVO) => {
  window.open(file.fileUrl, '_blank')
}

const toAcceptAttr = (exts: string) =>
  exts
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean)
    .map((item) => `.${item}`)
    .join(',')

const checkFileExt = (name: string, exts: string) => {
  if (!name.includes('.')) return false
  const ext = name.split('.').pop()?.toLowerCase() || ''
  return exts
    .split(',')
    .map((item) => item.trim().toLowerCase())
    .includes(ext)
}

const handleBack = () => {
  router.back()
}

onMounted(async () => {
  await loadSummary()
  getReviewMeeting(reviewMeetingId)
    .then((meeting) => {
      if (!projectInfo.value.meetingName) {
        projectInfo.value.meetingName = meeting.name
      }
      projectInfo.value.meetingHost = meeting.host
    })
    .catch(() => {})
})
</script>

<style scoped>
.page-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 22px;
  font-weight: 600;
  color: #333;
  margin-bottom: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid #e1e7f0;
}

.back-btn {
  font-size: 28px;
  color: #295abc;
  cursor: pointer;
  line-height: 1;
  margin-right: 2px;
  font-weight: 400;
}

.info-panel {
  background: linear-gradient(135deg, rgba(41, 90, 188, 0.06) 0%, rgba(41, 90, 188, 0.03) 100%);
  border: 1px solid rgba(41, 90, 188, 0.15);
  border-radius: 8px;
  padding: 18px 20px;
  margin-bottom: 20px;
}

.info-panel-title {
  font-size: 18px;
  font-weight: 600;
  color: #295abc;
  margin-bottom: 10px;
}

.info-panel-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.meta-left {
  display: flex;
  align-items: center;
  gap: 14px;
}

.meta-tag {
  display: inline-block;
  padding: 2px 10px;
  background-color: rgba(41, 90, 188, 0.1);
  color: #295abc;
  border-radius: 4px;
  font-size: 13px;
}

.meta-item,
.meta-right {
  font-size: 13px;
  color: #666;
}

.info-panel-footer {
  display: flex;
  gap: 32px;
  padding-top: 12px;
  border-top: 1px solid rgba(41, 90, 188, 0.12);
}

.info-footer-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.footer-label {
  font-size: 13px;
  color: #999;
  white-space: nowrap;
}

.footer-value {
  font-size: 14px;
  color: #333;
}

.footer-value em {
  color: #666;
  font-style: normal;
  margin-left: 6px;
}

.material-card {
  background-color: #fff;
  border: 1px solid #e6eaf2;
  border-radius: 8px;
  padding: 16px;
}

.material-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.toolbar-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.group-title {
  margin: 8px 0 10px;
  font-size: 14px;
  font-weight: 600;
  color: #606266;
}

.group-after {
  margin-top: 18px;
}

.required-flag {
  color: #fc4f54;
  margin-left: 4px;
}

.file-name {
  color: #333;
}

.file-empty {
  color: #909399;
}

.op-link {
  display: inline-block;
  color: #295abc;
  font-size: 13px;
  cursor: pointer;
  margin: 0 8px;
}

.op-link.disabled {
  color: #c0c4cc;
  cursor: not-allowed;
}

.hidden-upload-input {
  display: none;
}

.form-footer {
  margin-top: 16px;
}

.btn-default {
  min-width: 90px;
  height: 36px;
  border: 1px solid #dcdfe6;
  background-color: #fff;
  border-radius: 4px;
  color: #606266;
  cursor: pointer;
}

:deep(.material-table .el-table__header-wrapper th) {
  background-color: #f5f7fa;
}
</style>
