<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import QRCode from "qrcode";
import {
  adminApi,
  type AdminManualInspectionPayload,
  type AdminReportDetail,
  type AdminReportListItem,
} from "../../api/admin";
import OrderStatusTag from "../../components/OrderStatusTag.vue";

function createInspectionPayload(): AdminManualInspectionPayload {
  return {
    report_header: {
      report_no: "",
      report_title: "安心验检查单",
      report_status: "pending_publish",
      service_provider: "anxinyan",
      institution_name: "安心验",
      publish_time: "",
    },
    product_info: {
      product_name: "",
      category_name: "",
      brand_name: "",
      color: "",
      size_spec: "",
      serial_no: "",
    },
    result_info: {
      result_status: "authentic",
      result_text: "正品",
      result_desc: "",
    },
    appraisal_info: {
      appraiser_name: "",
      reviewer_name: "",
      appraisal_time: "",
    },
    valuation_info: {
      condition_grade: "",
      condition_desc: "",
      valuation_min: "",
      valuation_max: "",
      valuation_desc: "",
    },
    risk_notice_text: "",
  };
}

const loading = ref(false);
const detailLoading = ref(false);
const drawerVisible = ref(false);
const inspectionDrawerVisible = ref(false);
const inspectionSubmitting = ref(false);
const publishingId = ref<number | null>(null);
const rejectingId = ref<number | null>(null);
const traceVisibilitySavingId = ref<number | null>(null);
const detailQrDataUrl = ref("");

const keyword = ref("");
const serviceProvider = ref("");
const reportStatus = ref("");

const reports = ref<AdminReportListItem[]>([]);
const detail = ref<AdminReportDetail | null>(null);
const inspectionForm = ref<AdminManualInspectionPayload>(createInspectionPayload());
const route = useRoute();

const canPublishCurrentReport = computed(() => detail.value?.report_header.report_status === "pending_publish");
const canRejectCurrentReport = computed(
  () => detail.value?.report_header.report_type !== "inspection" && detail.value?.report_header.report_status === "pending_publish",
);
const canEditCurrentInspection = computed(
  () => detail.value?.report_header.report_type === "inspection" && detail.value?.report_header.report_status !== "published",
);
const inspectionDrawerTitle = computed(() => (inspectionForm.value.id ? "编辑补录检查单" : "补录检查单"));

const providerOptions = [
  { label: "全部服务", value: "" },
  { label: "实物鉴定", value: "anxinyan" },
  { label: "中检鉴定", value: "zhongjian" },
];

const statusOptions = [
  { label: "全部状态", value: "" },
  { label: "已发布", value: "published" },
  { label: "待发布", value: "pending_publish" },
  { label: "已驳回", value: "rejected" },
  { label: "草稿中", value: "draft" },
  { label: "已更新", value: "updated" },
  { label: "已作废", value: "invalid" },
];

const inspectionStatusOptions = [
  { label: "草稿保存", value: "draft" },
  { label: "待发布", value: "pending_publish" },
  { label: "直接发布", value: "published" },
];

const resultOptions = [
  { label: "正品", value: "authentic", text: "正品" },
  { label: "存疑", value: "uncertain", text: "存疑" },
  { label: "非正品", value: "not_authentic", text: "非正品" },
];

function applyProviderPreset(force = false) {
  const provider = inspectionForm.value.report_header.service_provider;
  const title = provider === "zhongjian" ? "中检检查单" : "安心验检查单";
  const institution = provider === "zhongjian" ? "中检合作机构" : "安心验";

  if (force || !inspectionForm.value.report_header.report_title) {
    inspectionForm.value.report_header.report_title = title;
  }
  if (force || !inspectionForm.value.report_header.institution_name) {
    inspectionForm.value.report_header.institution_name = institution;
  }
}

function syncResultText() {
  const matched = resultOptions.find((item) => item.value === inspectionForm.value.result_info.result_status);
  if (matched && !inspectionForm.value.result_info.result_text) {
    inspectionForm.value.result_info.result_text = matched.text;
  }
}

function previewEvidence(url: string) {
  if (!url) return;
  window.open(url, "_blank", "noopener,noreferrer");
}

function evidenceTypeLabel(fileType?: string) {
  return fileType === "image" ? "图片" : fileType === "video" ? "视频" : fileType === "pdf" ? "PDF" : "附件";
}

const imageEvidenceList = computed(() =>
  (detail.value?.evidence_attachments || []).filter((item) => item.file_type === "image"),
);

const fileEvidenceList = computed(() =>
  (detail.value?.evidence_attachments || []).filter((item) => item.file_type !== "image"),
);
const zhongjianReportImageList = computed(() =>
  (detail.value?.zhongjian_report_files || []).filter((item) => item.file_type === "image"),
);
const zhongjianReportFileList = computed(() =>
  (detail.value?.zhongjian_report_files || []).filter((item) => item.file_type !== "image"),
);

function openInspectionCreate() {
  inspectionForm.value = createInspectionPayload();
  applyProviderPreset(true);
  syncResultText();
  inspectionDrawerVisible.value = true;
}

function openInspectionEditFromDetail() {
  if (!detail.value) return;

  inspectionForm.value = {
    id: detail.value.report_header.id,
    report_header: {
      report_no: detail.value.report_header.report_no,
      report_title: detail.value.report_header.report_title,
      report_status: detail.value.report_header.report_status,
      service_provider: detail.value.report_header.service_provider,
      institution_name: detail.value.report_header.institution_name,
      publish_time: detail.value.report_header.publish_time || "",
    },
    product_info: {
      product_name: detail.value.product_info.product_name || "",
      category_name: detail.value.product_info.category_name || "",
      brand_name: detail.value.product_info.brand_name || "",
      color: detail.value.product_info.color || "",
      size_spec: detail.value.product_info.size_spec || "",
      serial_no: detail.value.product_info.serial_no || "",
    },
    result_info: {
      result_status: detail.value.result_info.result_status || "authentic",
      result_text: detail.value.result_info.result_text || "",
      result_desc: detail.value.result_info.result_desc || "",
    },
    appraisal_info: {
      appraiser_name: detail.value.appraisal_info.appraiser_name || "",
      reviewer_name: detail.value.appraisal_info.reviewer_name || "",
      appraisal_time: detail.value.appraisal_info.appraisal_time || "",
    },
    valuation_info: {
      condition_grade: detail.value.valuation_info.condition_grade || "",
      condition_desc: detail.value.valuation_info.condition_desc || "",
      valuation_min: detail.value.valuation_info.valuation_min ?? "",
      valuation_max: detail.value.valuation_info.valuation_max ?? "",
      valuation_desc: detail.value.valuation_info.valuation_desc || "",
    },
    risk_notice_text: detail.value.risk_notice_text || "",
  };
  inspectionDrawerVisible.value = true;
}

async function syncQrCode(url: string) {
  if (!/^https?:\/\//i.test(url)) {
    detailQrDataUrl.value = "";
    return;
  }

  try {
    detailQrDataUrl.value = await QRCode.toDataURL(url, {
      width: 220,
      margin: 1,
    });
  } catch (error) {
    console.error(error);
    detailQrDataUrl.value = "";
  }
}

async function fetchReports() {
  loading.value = true;
  try {
    const response = await adminApi.getReports({
      keyword: keyword.value,
      service_provider: serviceProvider.value,
      status: reportStatus.value,
    });
    if (response.code !== 0) {
      ElMessage.error(response.message || "报告列表加载失败");
      return;
    }
    reports.value = response.data.list;
  } catch (error) {
    console.error(error);
    ElMessage.error("报告列表加载失败");
  } finally {
    loading.value = false;
  }
}

async function loadDetail(id: number) {
  detailLoading.value = true;
  detailQrDataUrl.value = "";
  try {
    const response = await adminApi.getReportDetail(id);
    if (response.code !== 0) {
      ElMessage.error(response.message || "报告详情加载失败");
      return;
    }
    detail.value = response.data;
    await syncQrCode(response.data.verify_info.verify_qrcode_url || response.data.verify_info.report_page_url || "");
  } catch (error) {
    console.error(error);
    ElMessage.error("报告详情加载失败");
  } finally {
    detailLoading.value = false;
  }
}

async function openDetail(row: AdminReportListItem) {
  drawerVisible.value = true;
  await loadDetail(row.id);
}

function parseReportId(value: unknown) {
  const raw = Array.isArray(value) ? value[0] : value;
  const id = Number(raw || 0);
  return Number.isInteger(id) && id > 0 ? id : 0;
}

async function openDetailFromRouteQuery() {
  const reportId = parseReportId(route.query.report_id);
  if (!reportId) {
    return;
  }
  if (drawerVisible.value && detail.value?.report_header.id === reportId) {
    return;
  }
  drawerVisible.value = true;
  await loadDetail(reportId);
}

type PublishReportTarget = Pick<AdminReportListItem, "id" | "report_status" | "report_type" | "material_tag_bound"> | {
  id: number;
  report_status: string;
  report_type: string;
  material_tag_bound: boolean;
};
type RejectReportTarget = Pick<AdminReportListItem, "id" | "report_status" | "report_type"> | {
  id: number;
  report_status: string;
  report_type: string;
};
type ReportTraceVisibilityTarget = Pick<AdminReportListItem, "id" | "trace_info_visible">;

async function promptReportMaterialTagInput() {
  try {
    const result = await ElMessageBox.prompt("是否已鉴定完成并确定发布报告？", "绑定验真吊牌并发布报告", {
      type: "warning",
      inputPlaceholder: "请扫描验真吊牌二维码",
      inputPattern: /\S+/,
      inputErrorMessage: "请扫描验真吊牌二维码",
      confirmButtonText: "是的，去绑定验真吊牌",
      cancelButtonText: "取消",
      closeOnClickModal: false,
    });
    return String(result.value || "").trim();
  } catch {
    return "";
  }
}

async function publishReport(row: PublishReportTarget) {
  if (row.report_status !== "pending_publish") {
    ElMessage.warning("仅待发布报告可以执行发布");
    return;
  }

  const needMaterialTag = row.report_type !== "inspection" && !row.material_tag_bound;
  let qrInput = "";
  if (needMaterialTag) {
    qrInput = await promptReportMaterialTagInput();
    if (!qrInput) {
      return;
    }
  } else {
    try {
      await ElMessageBox.confirm("发布后用户端将可查看正式报告并进行验真，是否继续？", "发布报告", {
        type: "warning",
        confirmButtonText: "确认发布",
        cancelButtonText: "取消",
      });
    } catch {
      return;
    }
  }

  publishingId.value = row.id;
  try {
    const response = await adminApi.publishReport(row.id, qrInput);
    if (response.code !== 0) {
      ElMessage.error(response.message || "报告发布失败");
      return;
    }

    ElMessage.success(response.message || "报告已发布");
    await fetchReports();

    if (drawerVisible.value && detail.value?.report_header.id === row.id) {
      await loadDetail(row.id);
    }
  } catch (error) {
    console.error(error);
    ElMessage.error("报告发布失败");
  } finally {
    publishingId.value = null;
  }
}

async function rejectReport(row: RejectReportTarget) {
  if (row.report_status !== "pending_publish") {
    ElMessage.warning("仅待发布报告可以驳回");
    return;
  }
  if (row.report_type === "inspection") {
    ElMessage.warning("补录检查单不支持驳回复鉴");
    return;
  }

  let reason = "";
  try {
    const result = await ElMessageBox.prompt("请填写驳回原因，鉴定师将据此重新鉴定。", "驳回报告", {
      type: "warning",
      inputType: "textarea",
      inputPlaceholder: "例如：结论说明不完整、图片附件不清晰",
      inputPattern: /\S+/,
      inputErrorMessage: "请填写驳回原因",
      confirmButtonText: "确认驳回",
      cancelButtonText: "取消",
      closeOnClickModal: false,
    });
    reason = String(result.value || "").trim();
  } catch {
    return;
  }

  rejectingId.value = row.id;
  try {
    const response = await adminApi.rejectReport(row.id, reason);
    if (response.code !== 0) {
      ElMessage.error(response.message || "报告驳回失败");
      return;
    }

    ElMessage.success(response.message || "报告已驳回");
    await fetchReports();
    if (drawerVisible.value && detail.value?.report_header.id === row.id) {
      await loadDetail(row.id);
    }
  } catch (error: any) {
    console.error(error);
    ElMessage.error(error?.message || "报告驳回失败");
  } finally {
    rejectingId.value = null;
  }
}

function logSummary(data: Record<string, any>) {
  const status = data.report_status || "-";
  const version = data.report_version ? `v${data.report_version}` : "";
  const publishTime = data.publish_time ? ` · ${data.publish_time}` : "";
  const rejectReason = data.reject_reason || data.invalid_reason ? ` · ${data.reject_reason || data.invalid_reason}` : "";
  return [status, version].filter(Boolean).join(" / ") + publishTime + rejectReason;
}

function switchValueToBoolean(value: unknown) {
  if (typeof value === "boolean") return value;
  if (typeof value === "number") return value === 1;
  return ["1", "true", "yes", "on"].includes(String(value).trim().toLowerCase());
}

async function updateReportTraceVisibility(row: ReportTraceVisibilityTarget, value: unknown) {
  const visible = switchValueToBoolean(value);
  traceVisibilitySavingId.value = row.id;
  try {
    const response = await adminApi.updateReportTraceVisibility(row.id, visible);
    if (response.code !== 0) {
      ElMessage.error(response.message || "追溯信息开关保存失败");
      return;
    }

    const appliedVisible = Boolean(response.data.trace_info_visible);
    row.trace_info_visible = appliedVisible;

    const listItem = reports.value.find((item) => item.id === row.id);
    if (listItem) {
      listItem.trace_info_visible = appliedVisible;
    }
    if (detail.value?.report_header.id === row.id) {
      detail.value.report_header.trace_info_visible = appliedVisible;
    }

    ElMessage.success(response.message || (appliedVisible ? "追溯信息已设为显示" : "追溯信息已隐藏"));
  } catch (error) {
    console.error(error);
    ElMessage.error("追溯信息开关保存失败");
  } finally {
    traceVisibilitySavingId.value = null;
  }
}

function handleTraceVisibilityChange(row: ReportTraceVisibilityTarget, value: unknown) {
  void updateReportTraceVisibility(row, value);
}

function validateInspectionForm() {
  const { report_header, product_info, result_info } = inspectionForm.value;
  if (!report_header.report_title.trim()) {
    ElMessage.warning("请填写检查单标题");
    return false;
  }
  if (!report_header.institution_name.trim()) {
    ElMessage.warning("请填写出具机构");
    return false;
  }
  if (!product_info.product_name.trim()) {
    ElMessage.warning("请填写商品名称");
    return false;
  }
  if (!result_info.result_text.trim()) {
    ElMessage.warning("请填写鉴定结论");
    return false;
  }
  return true;
}

async function saveInspection() {
  if (!validateInspectionForm()) {
    return;
  }

  inspectionSubmitting.value = true;
  try {
    const response = await adminApi.saveInspectionReport(inspectionForm.value);
    if (response.code !== 0) {
      ElMessage.error(response.message || "检查单保存失败");
      return;
    }

    ElMessage.success(response.message || "检查单已保存");
    inspectionDrawerVisible.value = false;
    await fetchReports();
    drawerVisible.value = true;
    await loadDetail(response.data.id);
  } catch (error) {
    console.error(error);
    ElMessage.error("检查单保存失败");
  } finally {
    inspectionSubmitting.value = false;
  }
}

async function copyText(value: string, label: string) {
  if (!value) {
    ElMessage.warning(`${label}为空`);
    return;
  }

  try {
    if (navigator.clipboard?.writeText) {
      await navigator.clipboard.writeText(value);
    } else {
      const input = document.createElement("textarea");
      input.value = value;
      document.body.appendChild(input);
      input.select();
      document.execCommand("copy");
      document.body.removeChild(input);
    }
    ElMessage.success(`${label}已复制`);
  } catch (error) {
    console.error(error);
    ElMessage.error(`${label}复制失败`);
  }
}

onMounted(() => {
  applyProviderPreset(true);
  syncResultText();
  fetchReports();
  openDetailFromRouteQuery();
});

watch(
  () => route.query.report_id,
  () => {
    openDetailFromRouteQuery();
  },
);
</script>

<template>
  <el-card class="panel-card" shadow="never">
    <div class="filters-row" style="justify-content: space-between;">
      <div class="filters-row">
        <el-input v-model="keyword" placeholder="搜索报告编号 / 鉴定单号 / 订单号 / 商品名称" clearable style="width: 340px" />
        <el-select v-model="serviceProvider" placeholder="服务类型" style="width: 160px">
          <el-option v-for="item in providerOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select v-model="reportStatus" placeholder="报告状态" style="width: 160px">
          <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-button type="primary" @click="fetchReports">查询</el-button>
      </div>
      <el-button type="primary" plain @click="openInspectionCreate">补录检查单</el-button>
    </div>
  </el-card>

  <el-card class="panel-card orders-table" shadow="never">
    <el-table v-loading="loading" :data="reports" stripe>
      <el-table-column prop="report_no" label="报告编号" min-width="180" />
      <el-table-column prop="appraisal_no" label="鉴定单号" min-width="180" />
      <el-table-column prop="report_type_text" label="类型" min-width="120" />
      <el-table-column prop="report_title" label="报告标题" min-width="180" />
      <el-table-column prop="product_name" label="商品名称" min-width="220" />
      <el-table-column prop="service_provider_text" label="服务类型" min-width="120" />
      <el-table-column label="报告状态" min-width="120">
        <template #default="{ row }">
          <OrderStatusTag :status="row.report_status_text" />
        </template>
      </el-table-column>
      <el-table-column label="验真吊牌" min-width="120">
        <template #default="{ row }">
          <OrderStatusTag v-if="row.report_type !== 'inspection'" :status="row.material_tag_bound ? '已绑定' : '未绑定'" />
          <span v-else class="detail-label">不适用</span>
        </template>
      </el-table-column>
      <el-table-column label="追溯信息" min-width="130">
        <template #default="{ row }">
          <el-switch
            :model-value="row.trace_info_visible"
            :loading="traceVisibilitySavingId === row.id"
            inline-prompt
            active-text="显示"
            inactive-text="隐藏"
            @change="handleTraceVisibilityChange(row, $event)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="institution_name" label="出具机构" min-width="160" />
      <el-table-column prop="publish_time" label="发布时间" min-width="170" />
      <el-table-column label="操作" fixed="right" width="280">
        <template #default="{ row }">
          <el-button link type="primary" @click="openDetail(row)">查看详情</el-button>
          <el-button
            v-if="row.report_type === 'inspection' && row.report_status !== 'published'"
            link
            type="success"
            @click="openDetail(row).then(() => openInspectionEditFromDetail())"
          >
            编辑检查单
          </el-button>
          <el-button
            v-if="row.report_type !== 'inspection' && row.report_status === 'pending_publish'"
            link
            type="warning"
            :loading="publishingId === row.id"
            @click="publishReport(row)"
          >
            发布报告
          </el-button>
          <el-button
            v-if="row.report_type !== 'inspection' && row.report_status === 'pending_publish'"
            link
            type="danger"
            :loading="rejectingId === row.id"
            @click="rejectReport(row)"
          >
            驳回报告
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>

  <el-drawer v-model="drawerVisible" size="62%" title="报告详情">
    <div v-loading="detailLoading" v-if="detail" class="detail-grid">
      <div style="grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 12px; margin-bottom: 8px">
        <el-button v-if="canEditCurrentInspection" type="success" plain @click="openInspectionEditFromDetail">
          编辑检查单
        </el-button>
        <el-button
          v-if="canPublishCurrentReport"
          type="primary"
          :loading="publishingId === detail.report_header.id"
          @click="publishReport({
            id: detail.report_header.id,
            report_status: detail.report_header.report_status,
            report_type: detail.report_header.report_type,
            material_tag_bound: Boolean(detail.material_tag),
          })"
        >
          发布报告
        </el-button>
        <el-button
          v-if="canRejectCurrentReport"
          type="danger"
          plain
          :loading="rejectingId === detail.report_header.id"
          @click="rejectReport({
            id: detail.report_header.id,
            report_status: detail.report_header.report_status,
            report_type: detail.report_header.report_type,
          })"
        >
          驳回报告
        </el-button>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">报告概览</div>
        <div class="detail-card__desc">
          <div class="detail-label">报告编号</div>
          <div class="detail-value">{{ detail.report_header.report_no }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">报告类型</div>
          <div class="detail-value">{{ detail.report_header.report_type_text }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">报告标题</div>
          <div class="detail-value">{{ detail.report_header.report_title }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">报告状态</div>
          <div class="detail-value">
            <OrderStatusTag :status="detail.report_header.report_status_text" />
          </div>
        </div>
        <div v-if="detail.report_header.reject_reason" class="detail-card__desc">
          <div class="detail-label">驳回原因</div>
          <div class="detail-value">{{ detail.report_header.reject_reason }}</div>
        </div>
        <div v-if="detail.report_header.rejected_at" class="detail-card__desc">
          <div class="detail-label">驳回信息</div>
          <div class="detail-value">{{ detail.report_header.rejected_by_name || "-" }} / {{ detail.report_header.rejected_at }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">出具机构</div>
          <div class="detail-value">{{ detail.report_header.institution_name }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">追溯信息</div>
          <div class="detail-value report-visibility-control">
            <el-switch
              :model-value="detail.report_header.trace_info_visible"
              :loading="traceVisibilitySavingId === detail.report_header.id"
              inline-prompt
              active-text="显示"
              inactive-text="隐藏"
              @change="handleTraceVisibilityChange(detail.report_header, $event)"
            />
            <span>{{ detail.report_header.trace_info_visible ? "用户端显示追溯信息 tab" : "用户端隐藏追溯信息 tab" }}</span>
          </div>
        </div>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">验真吊牌</div>
        <template v-if="detail.report_header.report_type === 'inspection'">
          <div class="detail-card__desc">
            <div class="detail-value">补录检查单不需要绑定验真吊牌</div>
          </div>
        </template>
        <template v-else-if="detail.material_tag">
          <div class="detail-card__desc">
            <div class="detail-label">二维码链接</div>
            <div class="detail-value" style="word-break: break-all;">{{ detail.material_tag.qr_url }}</div>
          </div>
          <div class="detail-card__desc">
            <div class="detail-label">验真编码</div>
            <div class="detail-value">{{ detail.material_tag.verify_code }}</div>
          </div>
          <div class="detail-card__desc">
            <div class="detail-label">绑定时间</div>
            <div class="detail-value">{{ detail.material_tag.bound_at || "-" }}</div>
          </div>
        </template>
        <div v-else class="detail-card__desc">
          <div class="detail-value">未绑定，发布前需要扫描验真吊牌。</div>
        </div>
      </div>

      <div class="detail-card detail-card--wide">
        <div class="detail-card__title">审核记录</div>
        <div v-if="detail.audit_logs.length" class="report-log-list">
          <div v-for="log in detail.audit_logs" :key="`audit-${log.id}`" class="report-log-item">
            <div class="report-log-main">
              <span>{{ log.action_text }}</span>
              <span>{{ log.operator_name || "-" }}</span>
              <span>{{ log.created_at }}</span>
            </div>
            <div v-if="log.remark" class="report-log-remark">{{ log.remark }}</div>
            <div class="report-log-snapshot">{{ logSummary(log.after_data) }}</div>
          </div>
        </div>
        <div v-else class="detail-card__desc">
          <div class="detail-value">暂无审核记录</div>
        </div>
      </div>

      <div class="detail-card detail-card--wide">
        <div class="detail-card__title">修改记录</div>
        <div v-if="detail.change_logs.length" class="report-log-list">
          <div v-for="log in detail.change_logs" :key="`change-${log.id}`" class="report-log-item">
            <div class="report-log-main">
              <span>{{ log.action_text }}</span>
              <span>{{ log.operator_name || "-" }}</span>
              <span>{{ log.created_at }}</span>
            </div>
            <div v-if="log.remark" class="report-log-remark">{{ log.remark }}</div>
            <div class="report-log-snapshot">
              {{ logSummary(log.before_data) }} -> {{ logSummary(log.after_data) }}
            </div>
          </div>
        </div>
        <div v-else class="detail-card__desc">
          <div class="detail-value">暂无修改记录</div>
        </div>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">商品信息</div>
        <div class="detail-card__desc">
          <div class="detail-label">商品名称</div>
          <div class="detail-value">{{ detail.product_info.product_name || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">品类 / 品牌</div>
          <div class="detail-value">{{ detail.product_info.category_name || "-" }} / {{ detail.product_info.brand_name || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">颜色 / 规格</div>
          <div class="detail-value">{{ detail.product_info.color || "-" }} / {{ detail.product_info.size_spec || "-" }}</div>
        </div>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">鉴定结果</div>
        <div class="detail-card__desc">
          <div class="detail-label">结论</div>
          <div class="detail-value">{{ detail.result_info.result_text || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">说明</div>
          <div class="detail-value">{{ detail.result_info.result_desc || "-" }}</div>
        </div>
        <template v-if="detail.result_info.key_points?.length">
          <div v-for="(item, index) in detail.result_info.key_points" :key="`${item.point_code || item.point_name}-${index}`" class="detail-card__desc">
            <div class="detail-label">{{ item.point_name || "鉴定项" }}</div>
            <div class="detail-value">{{ item.point_value || "-" }}</div>
          </div>
        </template>
        <div v-if="detail.result_info.external_remark" class="detail-card__desc">
          <div class="detail-label">对外备注</div>
          <div class="detail-value">{{ detail.result_info.external_remark }}</div>
        </div>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">鉴定信息</div>
        <div class="detail-card__desc">
          <div class="detail-label">服务类型</div>
          <div class="detail-value">{{ detail.report_header.service_provider_text }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">鉴定师</div>
          <div class="detail-value">{{ detail.appraisal_info.appraiser_name || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">鉴定时间</div>
          <div class="detail-value">{{ detail.appraisal_info.appraisal_time || "-" }}</div>
        </div>
        <template v-if="detail.report_header.service_provider === 'zhongjian'">
          <div class="detail-card__desc">
            <div class="detail-label">中检报告编号</div>
            <div class="detail-value">{{ detail.report_header.zhongjian_report_no || "-" }}</div>
          </div>
          <div class="detail-card__desc">
            <div class="detail-label">报告录入人</div>
            <div class="detail-value">{{ detail.report_header.report_entry_admin_name || "-" }}</div>
          </div>
          <div class="detail-card__desc">
            <div class="detail-label">录入时间</div>
            <div class="detail-value">{{ detail.report_header.report_entered_at || "-" }}</div>
          </div>
        </template>
      </div>

      <div class="detail-card">
        <div class="detail-card__title">评级与估值</div>
        <div class="detail-card__desc">
          <div class="detail-label">成色评级</div>
          <div class="detail-value">{{ detail.valuation_info.condition_grade || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">成色说明</div>
          <div class="detail-value">{{ detail.valuation_info.condition_desc || "-" }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">估值区间</div>
          <div class="detail-value">¥{{ detail.valuation_info.valuation_min || 0 }} - ¥{{ detail.valuation_info.valuation_max || 0 }}</div>
        </div>
        <div class="detail-card__desc">
          <div class="detail-label">估值说明</div>
          <div class="detail-value">{{ detail.valuation_info.valuation_desc || "-" }}</div>
        </div>
      </div>

      <div class="detail-card" style="grid-column: 1 / -1">
        <div class="detail-card__title">证据附件</div>
        <div v-if="detail.evidence_attachments.length" class="report-evidence-stack">
          <div v-if="imageEvidenceList.length" class="report-evidence-section">
            <div class="report-evidence-section__title">图片证据</div>
            <div class="report-evidence-gallery">
              <div
                v-for="attachment in imageEvidenceList"
                :key="attachment.file_id"
                class="report-evidence-gallery__item"
                @click="previewEvidence(attachment.file_url)"
              >
                <img :src="attachment.thumbnail_url || attachment.file_url" :alt="attachment.name || '证据图片'" />
                <div class="report-evidence-gallery__caption">{{ attachment.name || "未命名图片" }}</div>
              </div>
            </div>
          </div>

          <div v-if="fileEvidenceList.length" class="report-evidence-section">
            <div class="report-evidence-section__title">视频 / 文档证据</div>
            <div class="report-evidence-list">
              <div v-for="attachment in fileEvidenceList" :key="attachment.file_id" class="report-evidence-card">
                <div class="report-evidence-card__preview" @click="previewEvidence(attachment.file_url)">
                  <div class="report-evidence-card__filetype">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                </div>
                <div class="report-evidence-card__body">
                  <div class="detail-value" style="margin-top: 0; word-break: break-word;">{{ attachment.name || attachment.file_url }}</div>
                  <div class="detail-label" style="margin-top: 6px;">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                  <el-button size="small" style="margin-top: 10px" @click="previewEvidence(attachment.file_url)">查看附件</el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="detail-card__desc">
          <div class="detail-value">当前报告未附带证据附件</div>
        </div>
      </div>

      <div v-if="detail.report_header.service_provider === 'zhongjian'" class="detail-card" style="grid-column: 1 / -1">
        <div class="detail-card__title">中检报告文件</div>
        <div v-if="detail.zhongjian_report_files.length" class="report-evidence-stack">
          <div v-if="zhongjianReportImageList.length" class="report-evidence-section">
            <div class="report-evidence-section__title">报告图片</div>
            <div class="report-evidence-gallery">
              <div
                v-for="attachment in zhongjianReportImageList"
                :key="attachment.file_id"
                class="report-evidence-gallery__item"
                @click="previewEvidence(attachment.file_url)"
              >
                <img :src="attachment.thumbnail_url || attachment.file_url" :alt="attachment.name || '中检报告图片'" />
                <div class="report-evidence-gallery__caption">{{ attachment.name || "未命名图片" }}</div>
              </div>
            </div>
          </div>

          <div v-if="zhongjianReportFileList.length" class="report-evidence-section">
            <div class="report-evidence-section__title">报告文档</div>
            <div class="report-evidence-list">
              <div v-for="attachment in zhongjianReportFileList" :key="attachment.file_id" class="report-evidence-card">
                <div class="report-evidence-card__preview" @click="previewEvidence(attachment.file_url)">
                  <div class="report-evidence-card__filetype">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                </div>
                <div class="report-evidence-card__body">
                  <div class="detail-value" style="margin-top: 0; word-break: break-word;">{{ attachment.name || attachment.file_url }}</div>
                  <div class="detail-label" style="margin-top: 6px;">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                  <el-button size="small" style="margin-top: 10px" @click="previewEvidence(attachment.file_url)">查看文件</el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="detail-card__desc">
          <div class="detail-value">当前报告未上传中检报告文件</div>
        </div>
      </div>

      <div class="detail-card" style="grid-column: 1 / -1">
        <div class="detail-card__title">扫码与公开链接</div>
        <div style="display: grid; grid-template-columns: 220px 1fr; gap: 24px; align-items: start;">
          <div
            style="width: 220px; height: 220px; border-radius: 16px; border: 1px dashed var(--admin-border); display: flex; align-items: center; justify-content: center; overflow: hidden; background: #fff;"
          >
            <el-image v-if="detailQrDataUrl" :src="detailQrDataUrl" fit="contain" style="width: 200px; height: 200px" />
            <div v-else style="padding: 16px; text-align: center; color: var(--admin-text-subtle); line-height: 1.7;">
              请先在系统配置中填写 H5 页面根地址，再生成可扫码的公开链接。
            </div>
          </div>
          <div style="display: grid; gap: 14px;">
            <div class="detail-card__desc" style="margin: 0;">
              <div class="detail-label">扫码打开报告页</div>
              <div class="detail-value" style="word-break: break-all;">{{ detail.verify_info.verify_qrcode_url || "-" }}</div>
              <el-button size="small" style="margin-top: 8px" @click="copyText(detail.verify_info.verify_qrcode_url, '报告链接')">复制报告链接</el-button>
            </div>
            <div class="detail-card__desc" style="margin: 0;">
              <div class="detail-label">H5 验真页</div>
              <div class="detail-value" style="word-break: break-all;">{{ detail.verify_info.verify_url || "-" }}</div>
              <el-button size="small" style="margin-top: 8px" @click="copyText(detail.verify_info.verify_url, '验真链接')">复制验真链接</el-button>
            </div>
            <div class="detail-card__desc" style="margin: 0;">
              <div class="detail-label">验真状态 / 次数</div>
              <div class="detail-value">{{ detail.verify_info.verify_status }} / {{ detail.verify_info.verify_count }}</div>
            </div>
          </div>
        </div>
      </div>

      <div class="detail-card" style="grid-column: 1 / -1">
        <div class="detail-card__title">风险说明</div>
        <div class="detail-card__desc">
          <div class="detail-value">{{ detail.risk_notice_text || "-" }}</div>
        </div>
      </div>
    </div>
  </el-drawer>

  <el-drawer v-model="inspectionDrawerVisible" size="56%" :title="inspectionDrawerTitle">
    <div style="display: grid; gap: 24px;">
      <el-card shadow="never">
        <template #header>基础信息</template>
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="检查单编号">
              <el-input v-model="inspectionForm.report_header.report_no" placeholder="可留空，系统自动生成" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检查单标题">
              <el-input v-model="inspectionForm.report_header.report_title" placeholder="请输入检查单标题" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="服务类型">
              <el-select v-model="inspectionForm.report_header.service_provider" style="width: 100%" @change="applyProviderPreset()">
                <el-option label="实物鉴定" value="anxinyan" />
                <el-option label="中检鉴定" value="zhongjian" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="保存状态">
              <el-select v-model="inspectionForm.report_header.report_status" style="width: 100%">
                <el-option v-for="item in inspectionStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="出具机构">
              <el-input v-model="inspectionForm.report_header.institution_name" placeholder="请输入出具机构" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="发布时间">
              <el-date-picker
                v-model="inspectionForm.report_header.publish_time"
                type="datetime"
                value-format="YYYY-MM-DD HH:mm:ss"
                placeholder="直接发布时可指定发布时间"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>

      <el-card shadow="never">
        <template #header>商品信息</template>
        <el-row :gutter="16">
          <el-col :span="12"><el-form-item label="商品名称"><el-input v-model="inspectionForm.product_info.product_name" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="品类"><el-input v-model="inspectionForm.product_info.category_name" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="品牌"><el-input v-model="inspectionForm.product_info.brand_name" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="颜色"><el-input v-model="inspectionForm.product_info.color" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="规格 / 尺寸"><el-input v-model="inspectionForm.product_info.size_spec" /></el-form-item></el-col>
          <el-col :span="24"><el-form-item label="序列号 / 编码"><el-input v-model="inspectionForm.product_info.serial_no" /></el-form-item></el-col>
        </el-row>
      </el-card>

      <el-card shadow="never">
        <template #header>鉴定结果</template>
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="结果类型">
              <el-select v-model="inspectionForm.result_info.result_status" style="width: 100%" @change="syncResultText">
                <el-option v-for="item in resultOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结果文案">
              <el-input v-model="inspectionForm.result_info.result_text" placeholder="例如：正品 / 存疑 / 非正品" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="结果说明">
              <el-input v-model="inspectionForm.result_info.result_desc" type="textarea" :rows="4" placeholder="请输入检查结论说明" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>

      <el-card shadow="never">
        <template #header>鉴定与估值信息</template>
        <el-row :gutter="16">
          <el-col :span="12"><el-form-item label="鉴定师"><el-input v-model="inspectionForm.appraisal_info.appraiser_name" /></el-form-item></el-col>
          <el-col :span="12">
            <el-form-item label="鉴定时间">
              <el-date-picker
                v-model="inspectionForm.appraisal_info.appraisal_time"
                type="datetime"
                value-format="YYYY-MM-DD HH:mm:ss"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12"><el-form-item label="成色评级"><el-input v-model="inspectionForm.valuation_info.condition_grade" placeholder="例如 A / B+" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="最低估值"><el-input v-model="inspectionForm.valuation_info.valuation_min" type="number" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="最高估值"><el-input v-model="inspectionForm.valuation_info.valuation_max" type="number" /></el-form-item></el-col>
          <el-col :span="24"><el-form-item label="成色说明"><el-input v-model="inspectionForm.valuation_info.condition_desc" type="textarea" :rows="3" /></el-form-item></el-col>
          <el-col :span="24"><el-form-item label="估值说明"><el-input v-model="inspectionForm.valuation_info.valuation_desc" type="textarea" :rows="3" /></el-form-item></el-col>
        </el-row>
      </el-card>

      <el-card shadow="never">
        <template #header>风险说明</template>
        <el-form-item label="页面说明文案">
          <el-input v-model="inspectionForm.risk_notice_text" type="textarea" :rows="4" placeholder="请输入风险提示与适用说明" />
        </el-form-item>
      </el-card>

      <div style="display: flex; justify-content: flex-end; gap: 12px;">
        <el-button @click="inspectionDrawerVisible = false">取消</el-button>
        <el-button type="primary" :loading="inspectionSubmitting" @click="saveInspection">保存检查单</el-button>
      </div>
    </div>
  </el-drawer>
</template>

<style scoped>
.report-evidence-stack {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 14px;
}

.report-evidence-section__title {
  color: var(--admin-text-main);
  font-size: 14px;
  font-weight: 700;
}

.report-evidence-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-top: 12px;
}

.report-evidence-gallery__item {
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid #efe8d9;
  background: #fcfaf5;
  cursor: pointer;
}

.report-evidence-gallery__item img {
  width: 100%;
  height: 180px;
  object-fit: cover;
  display: block;
}

.report-evidence-gallery__caption {
  padding: 10px 12px;
  color: var(--admin-text-main);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
  word-break: break-word;
}

.report-evidence-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px;
  margin-top: 12px;
}

.report-evidence-card {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 14px;
  padding: 14px;
  border-radius: 16px;
  background: #fcfaf5;
  border: 1px solid #efe8d9;
}

.report-evidence-card__preview {
  width: 96px;
  height: 96px;
  border-radius: 14px;
  border: 1px solid #efe8d9;
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: pointer;
}

.report-evidence-card__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.report-evidence-card__filetype {
  color: var(--admin-progress);
  font-size: 13px;
  font-weight: 700;
}

.report-evidence-card__body {
  min-width: 0;
}

.report-visibility-control {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.report-visibility-control span {
  color: var(--admin-text-subtle);
  font-size: 13px;
  font-weight: 500;
}

.detail-card--wide {
  grid-column: 1 / -1;
}

.report-log-list {
  display: grid;
  gap: 10px;
}

.report-log-item {
  display: grid;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--admin-border);
  border-radius: 8px;
  background: #fffdfa;
}

.report-log-main {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  color: var(--admin-text-main);
  font-size: 13px;
  font-weight: 700;
}

.report-log-remark,
.report-log-snapshot {
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.5;
  word-break: break-word;
}
</style>
