<script setup lang="ts">
import { computed } from "vue";
import { Document } from "@element-plus/icons-vue";

type ReviewDocItem = {
  id: string;
  name: string;
  ossKey: string;
  reviewKey: string | string[];
  rejectKey: string;
  rejectLabel: string;
};

const props = defineProps<{
  docView: Record<string, any>;
  canReject: boolean;
  isHigherReview: boolean;
  toReviewTagType: (
    itemKey: string | string[],
  ) => "success" | "danger" | "info";
  toReviewResultText: (itemKey: string | string[]) => string;
  getFileUrl: (ossKey: unknown) => string;
  isImageAttachment: (name: unknown, ossKey: unknown) => boolean;
  isPdfAttachment: (name: unknown, ossKey: unknown) => boolean;
  openFileUrl: (ossKey: unknown) => void;
  previewOssDocument: (
    ossKey: string,
    fileNameHint?: string,
  ) => void | Promise<void>;
  handleRejectMaterialItem: (itemKey: string, itemLabel: string) => void;
}>();

const fileDisplayName = (name: unknown, ossKey: unknown) => {
  const fileName = String(name ?? "").trim();
  if (fileName) {
    return fileName;
  }
  const key = String(ossKey ?? "").trim();
  const tail = key.split("/").pop() || key;
  return tail || "附件";
};

const previewFile = (name: unknown, ossKey: unknown) => {
  const key = String(ossKey ?? "").trim();
  if (!key) {
    return;
  }
  if (props.isPdfAttachment(name, key)) {
    void props.previewOssDocument(key, fileDisplayName(name, key));
    return;
  }
  props.openFileUrl(key);
};

const agendaItems = computed<ReviewDocItem[]>(() =>
  (Array.isArray(props.docView?.agendas) ? props.docView.agendas : []).map(
    (item: any, index: number) => ({
      id: `agenda-${index}`,
      name: fileDisplayName(item?.name, item?.ossKey),
      ossKey: String(item?.ossKey ?? "").trim(),
      reviewKey:
        item?.itemKey === "agenda:1" ? ["agenda:1", "agenda"] : item?.itemKey,
      rejectKey: String(item?.itemKey ?? ""),
      rejectLabel: `会议日程#${index + 1}`,
    }),
  ),
);

const invitationItems = computed<ReviewDocItem[]>(() =>
  (
    Array.isArray(props.docView?.invitations)
      ? props.docView.invitations
      : []
  ).map((item: any, index: number) => ({
    id: `invitation-${index}`,
    name: fileDisplayName(item?.name, item?.ossKey),
    ossKey: String(item?.ossKey ?? "").trim(),
    reviewKey: `invitation:${index + 1}`,
    rejectKey: `invitation:${index + 1}`,
    rejectLabel: `邀请函#${index + 1}`,
  })),
);

const sections = computed(() => [
  {
    key: "agenda",
    title: "会议日程",
    description: "支持多份材料，按单份逐项审核。",
    items: agendaItems.value,
  },
  {
    key: "signIn",
    title: "签到表",
    description: "核对签到记录是否完整、清晰。",
    items: [
      {
        id: "signInSheet",
        name: fileDisplayName(
          props.docView?.signInName,
          props.docView?.signInOssKey,
        ),
        ossKey: String(props.docView?.signInOssKey ?? "").trim(),
        reviewKey: "signInSheet",
        rejectKey: "signInSheet",
        rejectLabel: "签到表",
      },
    ],
  },
  {
    key: "themePhoto",
    title: "主题照片",
    description: "核对现场主题照片与会议主题是否匹配。",
    items: [
      {
        id: "themePhoto",
        name: fileDisplayName(
          props.docView?.themePhotoName,
          props.docView?.themePhotoOssKey,
        ),
        ossKey: String(props.docView?.themePhotoOssKey ?? "").trim(),
        reviewKey: "themePhoto",
        rejectKey: "themePhoto",
        rejectLabel: "主题照片",
      },
    ],
  },
  {
    key: "invitation",
    title: "邀请函",
    description: "支持多份材料，按单份逐项审核。",
    items: invitationItems.value,
  },
]);
</script>

<template>
  <div class="audit-doc-layout">
    <section
      v-for="section in sections"
      :key="section.key"
      class="audit-section-card"
    >
      <header class="audit-section-card__header">
        <div>
          <div class="audit-section-card__title">{{ section.title }}</div>
          <div class="audit-section-card__subtitle">
            {{ section.description }}
          </div>
        </div>
      </header>

      <div v-if="section.items.length" class="audit-doc-grid">
        <article
          v-for="item in section.items"
          :key="item.id"
          class="audit-doc-card"
        >
          <div class="audit-doc-card__preview">
            <div v-if="!item.ossKey" class="audit-doc-card__empty">未上传</div>
            <el-image
              v-else-if="
                isImageAttachment(item.name, item.ossKey) &&
                getFileUrl(item.ossKey)
              "
              :src="getFileUrl(item.ossKey)"
              fit="cover"
              :preview-src-list="[getFileUrl(item.ossKey)]"
              :preview-teleported="true"
              class="audit-doc-card__image"
            />
            <button
              v-else-if="isPdfAttachment(item.name, item.ossKey)"
              class="audit-doc-card__pdf"
              type="button"
              :title="item.name"
              @click="previewFile(item.name, item.ossKey)"
            >
              <el-icon class="audit-doc-card__pdf-icon"><Document /></el-icon>
              <span class="audit-doc-card__pdf-label">PDF</span>
            </button>
            <el-button
              v-else
              size="small"
              type="primary"
              plain
              :disabled="!item.ossKey"
              @click="previewFile(item.name, item.ossKey)"
            >
              查看文件
            </el-button>
          </div>

          <div class="audit-doc-card__content">
            <div class="audit-doc-card__name" :title="item.name">
              {{ item.name }}
            </div>
            <div class="audit-doc-card__actions">
              <el-tag
                v-if="!isHigherReview"
                size="small"
                :type="toReviewTagType(item.reviewKey)"
              >
                {{ toReviewResultText(item.reviewKey) }}
              </el-tag>
              <el-button
                size="small"
                type="primary"
                plain
                :disabled="!item.ossKey"
                @click="previewFile(item.name, item.ossKey)"
              >
                查看
              </el-button>
              <el-button
                v-if="canReject && !isHigherReview"
                size="small"
                type="danger"
                plain
                @click="
                  handleRejectMaterialItem(item.rejectKey, item.rejectLabel)
                "
              >
                不通过
              </el-button>
            </div>
          </div>
        </article>
      </div>

      <el-empty v-else description="暂无已上传材料" />
    </section>
  </div>
</template>

<style scoped>
.audit-doc-layout {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.audit-section-card {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.05);
  overflow: hidden;
}

.audit-section-card__header {
  padding: 18px 24px 16px;
  border-bottom: 1px solid #f1f5f9;
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
}

.audit-section-card__title {
  font-size: 16px;
  font-weight: 600;
  color: #1e293b;
}

.audit-section-card__subtitle {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.5;
  color: #64748b;
}

.audit-doc-grid {
  padding: 20px 24px 24px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}

.audit-doc-card {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background: #fff;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.audit-doc-card__preview {
  min-height: 168px;
  padding: 16px;
  background: #f8fafc;
  display: flex;
  align-items: center;
  justify-content: center;
}

.audit-doc-card__image {
  width: 100%;
  height: 136px;
  border-radius: 10px;
  border: 1px solid #e2e8f0;
  display: block;
}

.audit-doc-card__empty {
  width: 100%;
  height: 136px;
  border-radius: 10px;
  border: 1px dashed #cbd5e1;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  font-size: 13px;
}

.audit-doc-card__pdf {
  width: 100%;
  height: 136px;
  border: 1px solid #dbe4f0;
  border-radius: 10px;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: #475569;
  cursor: pointer;
}

.audit-doc-card__pdf-icon {
  font-size: 28px;
}

.audit-doc-card__pdf-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.audit-doc-card__content {
  padding: 14px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.audit-doc-card__name {
  min-height: 40px;
  font-size: 13px;
  line-height: 1.5;
  color: #1e293b;
  word-break: break-word;
}

.audit-doc-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (max-width: 768px) {
  .audit-doc-grid {
    padding: 16px;
    grid-template-columns: 1fr;
  }
}
</style>
