<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  adminApi,
  type AdminFileAsset,
  type AdminAppraisalTaskDetail,
  type AdminAppraisalTaskListItem,
  type AdminAssignableAppraiserItem,
  type AdminCategoryItem,
} from "../../api/admin";
import OrderStatusTag from "../../components/OrderStatusTag.vue";
import { getAdminInfo } from "../../utils/auth";

const loading = ref(false);
const detailLoading = ref(false);
const drawerVisible = ref(false);
const resultSubmitting = ref(false);
const supplementSubmitting = ref(false);
const assigneeDialogVisible = ref(false);
const assigneeOptionsLoading = ref(false);
const assigneeSubmitting = ref(false);
const materialTagBinding = ref(false);
const assigneeOptions = ref<AdminAssignableAppraiserItem[]>([]);
const selectedAssigneeId = ref(0);
const evidenceUploading = ref(false);
const appraisalTemplateLoading = ref(false);
const transferTagNo = ref("");
const transferScanLoading = ref(false);
const zhongjianReportNo = ref("");
const zhongjianReportFiles = ref<AdminFileAsset[]>([]);
const zhongjianReportUploading = ref(false);
const zhongjianReportSubmitting = ref(false);

const keyword = ref("");
const taskStage = ref("");
const status = ref("");
const serviceProvider = ref("");
const detailTab = ref("overview");
const activeWorkTab = ref("result");
const formRenderKey = ref(0);
const workbenchAsideRef = ref<HTMLElement | null>(null);
const evidenceInputRef = ref<HTMLInputElement | null>(null);
const zhongjianReportFileInputRef = ref<HTMLInputElement | null>(null);
const materialTagInput = ref("");

const tasks = ref<AdminAppraisalTaskListItem[]>([]);
const categories = ref<AdminCategoryItem[]>([]);
const detail = ref<AdminAppraisalTaskDetail | null>(null);
const currentAppraisalTemplate = ref<AdminAppraisalTaskDetail["appraisal_template"]>(null);
const resultAttachments = ref<
  Array<{
    file_id: string;
    file_url: string;
    thumbnail_url: string;
    name?: string;
    file_type?: string;
    mime_type?: string;
  }>
>([]);
const resultKeyPoints = ref<
  Array<{
    point_code: string;
    point_name: string;
    point_type: "text" | "textarea" | "select" | "boolean";
    options: string[];
    sort_order: number;
    is_required: boolean;
    point_value: string;
    point_remark: string;
  }>
>([]);
const resultForm = reactive({
  result_text: "",
  result_desc: "",
  condition_grade: "",
  condition_desc: "",
  valuation_min: 0,
  valuation_max: 0,
  valuation_desc: "",
  external_remark: "",
  internal_remark: "",
});
const productForm = reactive({
  category_id: 0,
  product_name: "",
  category_name: "",
  brand_name: "",
  color: "",
  size_spec: "",
  serial_no: "",
});
const supplementForm = reactive({
  reason: "",
  deadline: "",
  items: [{ item_name: "", guide_text: "", is_required: true }],
});

const stageOptions = [
  { label: "全部阶段", value: "" },
  { label: "鉴定", value: "first_review" },
];

const statusOptions = [
  { label: "全部状态", value: "" },
  { label: "待处理", value: "pending" },
  { label: "处理中", value: "processing" },
  { label: "待用户补料", value: "returned" },
  { label: "已提交", value: "submitted" },
  { label: "已完成", value: "completed" },
];

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

const detailTabOptions = [
  { label: "任务信息", value: "overview" },
  { label: "资料与轨迹", value: "materials" },
  { label: "处理工作台", value: "actions" },
];

const usageStatusMap: Record<string, string> = {
  new: "全新未使用",
  light_use: "轻微使用痕迹",
  used: "长期使用",
};

const supplementStatusMap: Record<string, string> = {
  pending: "待处理",
  closed: "已关闭",
  completed: "已完成",
};

const materialStatusMap: Record<string, string> = {
  pending: "待补充",
  uploaded: "已上传",
  optional: "选填",
  completed: "已完成",
};

const usageStatusText = computed(() => {
  const value = detail.value?.extra_info.usage_status || "";
  return value ? usageStatusMap[value] || value : "-";
});

const productTitle = computed(() => {
  if (!detail.value) {
    return "待完善物品信息";
  }
  return detail.value.product_info.product_name || "待完善物品信息";
});

const productMetaText = computed(() => {
  if (!detail.value) {
    return "物品信息待完善";
  }
  const parts = [
    detail.value.product_info.category_name,
    detail.value.product_info.brand_name,
  ].filter(Boolean);

  return parts.length ? parts.join(" / ") : "物品信息待完善";
});

type ResultFormSeed = {
  result_text: string;
  result_desc: string;
  condition_grade: string;
  condition_desc?: string;
  valuation_min: number;
  valuation_max: number;
  valuation_desc?: string;
  attachments: Array<{
    file_id: string;
    file_url: string;
    thumbnail_url: string;
    name?: string;
    file_type?: string;
    mime_type?: string;
  }>;
  external_remark: string;
  internal_remark: string;
  key_points: Array<{
    point_code: string;
    point_name: string;
    point_value: string;
    point_remark: string;
  }>;
};

function hasResultSeedValue(result: ResultFormSeed) {
  return Boolean(
    result.result_text ||
      result.result_desc ||
      result.condition_grade ||
      result.condition_desc ||
      result.valuation_min ||
      result.valuation_max ||
      result.valuation_desc ||
      result.attachments?.length ||
      result.key_points?.some((item) => item.point_value || item.point_remark) ||
      result.external_remark ||
      result.internal_remark,
  );
}

function resolveResultFormSeed(data: AdminAppraisalTaskDetail): ResultFormSeed {
  if (!hasResultSeedValue(data.result_info) && data.prefill_result_info) {
    return data.prefill_result_info;
  }

  return data.result_info;
}

const currentResultLabel = computed(() => {
  if (!detail.value) {
    return "暂未填写";
  }
  if (detail.value.result_info.result_text) {
    return detail.value.result_info.result_text;
  }

  const latestStageResult = [...detail.value.stage_tasks]
    .sort((a, b) => {
      const aRank = a.task_stage === "first_review" ? 2 : 1;
      const bRank = b.task_stage === "first_review" ? 2 : 1;
      return bRank - aRank;
    })
    .find((item) => item.result_text);

  return latestStageResult?.result_text || "暂未填写";
});

const reviewPrefillHint = computed(() => {
  if (!detail.value) {
    return "";
  }

  return !hasResultSeedValue(detail.value.result_info) && detail.value.prefill_result_info
    ? `已默认带入${detail.value.prefill_result_info.source_stage_text}结论，可只修改存在差异的字段。`
    : "";
});

const supplementStatusText = computed(() => {
  if (!detail.value?.supplement_task) {
    return "当前暂无待处理补资料任务";
  }
  const task = detail.value.supplement_task;
  return `${supplementStatusMap[task.status] || task.status} · #${task.id}${task.deadline ? ` · 截止 ${task.deadline}` : ""}`;
});

const isTaskReadonly = computed(() => {
  if (!detail.value) {
    return false;
  }
  return (
    ["submitted", "completed"].includes(detail.value.task_info.status) ||
    (Boolean(detail.value.task_info.submitted_at) && Boolean(detail.value.report_summary))
  );
});

const reportDraftHint = computed(() => {
  if (!detail.value?.report_summary) {
    return "";
  }
  return `已生成报告草稿：${detail.value.report_summary.report_no} · ${detail.value.report_summary.report_status_text}`;
});

const canBindMaterialTag = computed(() => {
  if (!detail.value?.report_summary) {
    return false;
  }
  return detail.value.report_summary.report_status !== "published" && !detail.value.material_tag;
});

const isZhongjianTask = computed(() => detail.value?.task_info.service_provider === "zhongjian");
const canRequestSupplement = computed(() => detail.value?.task_info.status !== "completed");
const currentAdmin = computed(() => getAdminInfo());
const canClaimTask = computed(() => {
  if (!detail.value || isTaskReadonly.value) {
    return false;
  }
  const assigneeId = detail.value.task_info.assignee_id || 0;
  return assigneeId <= 0 && Boolean(currentAdmin.value?.id);
});

async function fetchTasks() {
  loading.value = true;
  try {
    const response = await adminApi.getAppraisalTasks({
      keyword: keyword.value,
      task_stage: taskStage.value,
      status: status.value,
      service_provider: serviceProvider.value,
    });
    tasks.value = response.data.list;
  } catch (error) {
    console.error(error);
    ElMessage.error("鉴定任务列表加载失败");
  } finally {
    loading.value = false;
  }
}

async function fetchCategories() {
  try {
    const response = await adminApi.getCategories();
    categories.value = response.data.list;
  } catch (error) {
    console.error(error);
    ElMessage.error("品类列表加载失败");
  }
}

function resetSupplementForm() {
  if (detail.value?.supplement_task) {
    applySupplementForm(detail.value);
    formRenderKey.value += 1;
    return;
  }

  supplementForm.reason = "";
  supplementForm.deadline = "";
  supplementForm.items.splice(0, supplementForm.items.length, {
    item_name: "",
    guide_text: "",
    is_required: true,
  });
  formRenderKey.value += 1;
}

function hydrateDetail(data: AdminAppraisalTaskDetail) {
  detail.value = data;
  detailTab.value = "overview";
  activeWorkTab.value = data.task_info.service_provider === "zhongjian" ? "zhongjian" : (data.supplement_task ? "supplement" : "result");
  applyProductForm(data.product_info);
  const resultSeed = resolveResultFormSeed(data);
  applyResultForm(resultSeed);
  applyAppraisalTemplate(data.appraisal_template, resultSeed.key_points || []);
  applyZhongjianReportForm(data);
  applySupplementForm(data);
  formRenderKey.value += 1;
}

function applyProductForm(data: AdminAppraisalTaskDetail["product_info"]) {
  Object.assign(productForm, {
    category_id: data.category_id || 0,
    product_name: data.product_name || "",
    category_name: data.category_name || "",
    brand_name: data.brand_name || "",
    color: data.color || "",
    size_spec: data.size_spec || "",
    serial_no: data.serial_no || "",
  });
}

function applyResultForm(data: ResultFormSeed) {
  Object.assign(resultForm, {
    result_text: data.result_text || "",
    result_desc: data.result_desc || "",
    condition_grade: data.condition_grade || "",
    condition_desc: data.condition_desc || "",
    valuation_min: data.valuation_min || 0,
    valuation_max: data.valuation_max || 0,
    valuation_desc: data.valuation_desc || "",
    external_remark: data.external_remark || "",
    internal_remark: data.internal_remark || "",
  });
  resultAttachments.value = [...(data.attachments || [])];
}

function applyAppraisalTemplate(
  template: AdminAppraisalTaskDetail["appraisal_template"],
  savedKeyPoints: ResultFormSeed["key_points"] = [],
) {
  currentAppraisalTemplate.value = template;
  if (!template) {
    resultKeyPoints.value = [];
    return;
  }

  const savedMap = new Map((savedKeyPoints || []).map((item) => [item.point_code, item]));
  resultKeyPoints.value = template.key_points.map((point) => {
    const saved = savedMap.get(point.point_code);
    return {
      point_code: point.point_code,
      point_name: point.point_name,
      point_type: point.point_type,
      options: [...(point.options || [])],
      sort_order: point.sort_order,
      is_required: point.is_required,
      point_value: saved?.point_value ?? point.point_value ?? "",
      point_remark: saved?.point_remark ?? point.point_remark ?? "",
    };
  });

}

function applySupplementForm(data: Pick<AdminAppraisalTaskDetail, "supplement_task">) {
  if (data.supplement_task) {
    supplementForm.reason = data.supplement_task.reason || "";
    supplementForm.deadline = data.supplement_task.deadline || "";
    supplementForm.items.splice(
      0,
      supplementForm.items.length,
      ...(data.supplement_task.items.length
        ? data.supplement_task.items.map((item) => ({
            item_name: item.item_name,
            guide_text: item.guide_text,
            is_required: item.is_required,
          }))
        : [{ item_name: "", guide_text: "", is_required: true }]),
    );
    return;
  }

  supplementForm.reason = "";
  supplementForm.deadline = "";
  supplementForm.items.splice(0, supplementForm.items.length, {
    item_name: "",
    guide_text: "",
    is_required: true,
  });
}

function applyZhongjianReportForm(data: AdminAppraisalTaskDetail) {
  zhongjianReportNo.value = data.zhongjian_report?.report_no || "";
  zhongjianReportFiles.value = [...(data.zhongjian_report?.files || [])];
}

function resetResultForm() {
  if (!detail.value) return;
  applyProductForm(detail.value.product_info);
  const resultSeed = resolveResultFormSeed(detail.value);
  applyResultForm(resultSeed);
  applyAppraisalTemplate(detail.value.appraisal_template, resultSeed.key_points || []);
  formRenderKey.value += 1;
}

function resetZhongjianReportForm() {
  if (!detail.value) return;
  applyZhongjianReportForm(detail.value);
}

function openSupplementWorkbench() {
  if (isTaskReadonly.value) {
    return;
  }
  detailTab.value = "actions";
  activeWorkTab.value = "supplement";
}

function returnToResultWorkbench() {
  resetSupplementForm();
  activeWorkTab.value = "result";
}

async function loadDetail(id: number) {
  detailLoading.value = true;
  try {
    const response = await adminApi.getAppraisalTaskDetail(id);
    hydrateDetail(response.data);
  } catch (error) {
    console.error(error);
    ElMessage.error("鉴定任务详情加载失败");
  } finally {
    detailLoading.value = false;
  }
}

async function openAssigneeDialog() {
  if (!detail.value) return;
  assigneeDialogVisible.value = true;
  assigneeOptionsLoading.value = true;
  selectedAssigneeId.value = detail.value.task_info.assignee_id || 0;
  try {
    const response = await adminApi.getAppraisalTaskAssignableAdmins(detail.value.task_info.id);
    assigneeOptions.value = response.data.list;
  } catch (error) {
    console.error(error);
    ElMessage.error("鉴定师列表加载失败");
  } finally {
    assigneeOptionsLoading.value = false;
  }
}

async function submitAssigneeAssign() {
  if (!detail.value || !selectedAssigneeId.value) {
    ElMessage.warning("请先选择处理人");
    return;
  }

  assigneeSubmitting.value = true;
  try {
    const response = await adminApi.assignAppraisalTask({
      id: detail.value.task_info.id,
      assignee_id: selectedAssigneeId.value,
    });
    ElMessage.success(response.message || "处理人已分配");
    assigneeDialogVisible.value = false;
    await loadDetail(detail.value.task_info.id);
    await fetchTasks();
  } catch (error) {
    console.error(error);
    ElMessage.error("处理人分配失败");
  } finally {
    assigneeSubmitting.value = false;
  }
}

async function claimTask() {
  if (!detail.value || !currentAdmin.value?.id) {
    return;
  }

  assigneeSubmitting.value = true;
  try {
    const response = await adminApi.assignAppraisalTask({
      id: detail.value.task_info.id,
      assignee_id: currentAdmin.value.id,
    });
    ElMessage.success(response.message || "任务已认领");
    await loadDetail(detail.value.task_info.id);
    await fetchTasks();
  } catch (error) {
    console.error(error);
    ElMessage.error("任务认领失败");
  } finally {
    assigneeSubmitting.value = false;
  }
}

async function openDetail(row: AdminAppraisalTaskListItem) {
  drawerVisible.value = true;
  detail.value = null;
  detailTab.value = "overview";
  activeWorkTab.value = row.service_provider === "zhongjian" ? "zhongjian" : "result";
  await loadDetail(row.id);
}

async function scanTransferTag() {
  const internalTagNo = transferTagNo.value.trim();
  if (!internalTagNo) {
    ElMessage.warning("请扫描内部流转码");
    return;
  }

  transferScanLoading.value = true;
  try {
    const response = await adminApi.scanAppraisalTransferTag(internalTagNo);
    drawerVisible.value = true;
    detail.value = null;
    await loadDetail(response.data.task_id);
    detailTab.value = "actions";
    activeWorkTab.value = response.data.service_provider === "zhongjian" ? "zhongjian" : "result";
    ElMessage.success(`${response.data.service_provider_text}任务已打开`);
    await fetchTasks();
  } catch (error: any) {
    console.error(error);
    ElMessage.error(error?.message || "内部流转码识别失败");
  } finally {
    transferScanLoading.value = false;
  }
}

function previewFiles(files: Array<{ file_url: string }>, current: string) {
  if (!files.length) return;
  window.open(current, "_blank", "noopener,noreferrer");
}

function triggerEvidenceUpload() {
  if (isTaskReadonly.value) {
    return;
  }
  evidenceInputRef.value?.click();
}

async function handleEvidenceFileSelect(event: Event) {
  const target = event.target as HTMLInputElement;
  const files = Array.from(target.files || []);
  if (!files.length) {
    return;
  }

  evidenceUploading.value = true;
  try {
    for (const file of files) {
      const response = await adminApi.uploadAppraisalEvidenceFile(file);
      resultAttachments.value.push(response.data);
    }
    ElMessage.success("附件上传成功");
  } catch (error) {
    console.error(error);
    ElMessage.error("附件上传失败");
  } finally {
    evidenceUploading.value = false;
    target.value = "";
  }
}

function triggerZhongjianReportUpload() {
  if (isTaskReadonly.value) {
    return;
  }
  zhongjianReportFileInputRef.value?.click();
}

async function handleZhongjianReportFileSelect(event: Event) {
  const target = event.target as HTMLInputElement;
  const files = Array.from(target.files || []);
  if (!files.length) {
    return;
  }

  zhongjianReportUploading.value = true;
  try {
    for (const file of files) {
      const response = await adminApi.uploadAppraisalEvidenceFile(file);
      zhongjianReportFiles.value.push(response.data);
    }
    ElMessage.success("中检报告文件已上传");
  } catch (error) {
    console.error(error);
    ElMessage.error("中检报告文件上传失败");
  } finally {
    zhongjianReportUploading.value = false;
    target.value = "";
  }
}

async function removeZhongjianReportFile(fileUrl: string) {
  try {
    await adminApi.deleteAppraisalEvidenceFile(fileUrl);
    zhongjianReportFiles.value = zhongjianReportFiles.value.filter((item) => item.file_url !== fileUrl);
    ElMessage.success("报告文件已删除");
  } catch (error) {
    console.error(error);
    ElMessage.error("报告文件删除失败");
  }
}

async function removeEvidenceAttachment(fileUrl: string) {
  try {
    await adminApi.deleteAppraisalEvidenceFile(fileUrl);
    resultAttachments.value = resultAttachments.value.filter((item) => item.file_url !== fileUrl);
    ElMessage.success("附件已删除");
  } catch (error) {
    console.error(error);
    ElMessage.error("附件删除失败");
  }
}

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

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

function selectedCategoryName(categoryId: number) {
  return categories.value.find((item) => item.id === categoryId)?.name || "";
}

async function handleProductCategoryChange(categoryId: number) {
  productForm.category_id = categoryId || 0;
  productForm.category_name = selectedCategoryName(categoryId);
  if (!categoryId || !detail.value) {
    currentAppraisalTemplate.value = null;
    resultKeyPoints.value = [];
    return;
  }

  appraisalTemplateLoading.value = true;
  try {
    const response = await adminApi.getCategoryAppraisalTemplates(categoryId);
    const template = response.data.template || response.data.list[0] || null;

    if (!template) {
      applyAppraisalTemplate(null);
      ElMessage.warning("当前品类模板加载失败");
      return;
    }

    applyAppraisalTemplate({
      id: template.id || 0,
      name: template.name,
      code: template.code,
      service_provider: template.service_provider,
      service_provider_text: template.service_provider_text,
      result_options: template.result_options,
      condition_options: template.condition_options,
      valuation_hint: template.valuation_hint,
      key_points: template.key_points.map((point) => ({
        point_code: point.point_code,
        point_name: point.point_name,
        point_type: point.point_type,
        options: [...(point.options || [])],
        sort_order: point.sort_order,
        is_required: point.is_required,
        point_value: "",
        point_remark: "",
      })),
    });
    formRenderKey.value += 1;
  } catch (error) {
    console.error(error);
    ElMessage.error("鉴定模板加载失败");
  } finally {
    appraisalTemplateLoading.value = false;
  }
}

function formatMaterialStatus(value: string) {
  return materialStatusMap[value] || value;
}

function formatMaterialSource(value: string) {
  return value === "supplement" ? "补交资料" : "初始资料";
}

function normalizedProductForm() {
  return {
    category_id: productForm.category_id,
    product_name: productForm.product_name.trim(),
    category_name: productForm.category_name.trim(),
    brand_name: productForm.brand_name.trim(),
    color: productForm.color.trim(),
    size_spec: productForm.size_spec.trim(),
    serial_no: productForm.serial_no.trim(),
  };
}

function normalizedKeyPoints() {
  return resultKeyPoints.value.map((item) => ({
    point_code: item.point_code,
    point_name: item.point_name,
    point_value: item.point_value.trim(),
    point_remark: item.point_remark.trim(),
  }));
}

function validateRequiredKeyPoints() {
  const missing = resultKeyPoints.value.find((item) => item.is_required && !item.point_value.trim());
  if (missing) {
    ElMessage.warning(`请填写鉴定模板项：${missing.point_name}`);
    return false;
  }
  return true;
}

function hasProductFormValue() {
  const product = normalizedProductForm();
  return Boolean(product.product_name || product.category_name || product.brand_name);
}

async function submitResult(action: "save" | "submit") {
  if (!detail.value) return;
  if (detail.value.task_info.service_provider === "zhongjian") {
    ElMessage.warning("中检订单请在中检报告录入页提交");
    activeWorkTab.value = "zhongjian";
    return;
  }
  if (action === "submit" && !resultForm.result_text.trim()) {
    ElMessage.warning("提交前请先填写鉴定结论");
    return;
  }
  if (action === "submit" && !hasProductFormValue()) {
    ElMessage.warning("提交前请先完善物品信息");
    return;
  }
  if (action === "submit" && !validateRequiredKeyPoints()) {
    return;
  }
  let qrInput = "";
  if (action === "submit") {
    qrInput = await promptPublishMaterialTagInput();
    if (!qrInput) {
      return;
    }
  }
  resultSubmitting.value = true;
  try {
    const response = await adminApi.saveAppraisalTaskResult({
      id: detail.value.task_info.id,
      action,
      product_info: normalizedProductForm(),
      ...resultForm,
      attachments: resultAttachments.value,
      key_points: normalizedKeyPoints(),
      ...(qrInput ? { qr_input: qrInput } : {}),
    });
    ElMessage.success(response.message || (action === "submit" ? "验真吊牌已绑定，报告已发布" : "结论已保存"));
    await loadDetail(detail.value.task_info.id);
    await fetchTasks();
  } catch (error) {
    console.error(error);
    ElMessage.error(action === "submit" ? "结论提交失败" : "结论保存失败");
  } finally {
    resultSubmitting.value = false;
  }
}

async function publishCurrentTaskWithMaterialTag(qrInput: string) {
  if (!detail.value) return;

  await adminApi.publishAppraisalTaskWithMaterialTag({
    id: detail.value.task_info.id,
    qr_input: qrInput,
  });
  ElMessage.success("验真吊牌已绑定，报告已发布");
  await loadDetail(detail.value.task_info.id);
  await fetchTasks();
}

async function bindMaterialTag() {
  const qrInput = materialTagInput.value.trim();
  if (!qrInput) {
    ElMessage.warning("请扫描或粘贴吊牌二维码链接");
    return;
  }

  materialTagBinding.value = true;
  try {
    await publishCurrentTaskWithMaterialTag(qrInput);
    materialTagInput.value = "";
  } catch (error: any) {
    console.error(error);
    ElMessage.error(error?.message || "验真吊牌绑定或报告发布失败");
  } finally {
    materialTagBinding.value = false;
  }
}

async function promptPublishMaterialTagInput() {
  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 submitZhongjianReport() {
  if (!detail.value) return;
  if (!isZhongjianTask.value) {
    ElMessage.warning("当前不是中检订单");
    return;
  }
  if (!zhongjianReportNo.value.trim()) {
    ElMessage.warning("请填写中检报告编号");
    return;
  }
  if (!resultForm.result_text.trim()) {
    ElMessage.warning("请填写鉴定结论");
    activeWorkTab.value = "result";
    return;
  }
  if (!hasProductFormValue()) {
    ElMessage.warning("提交前请先完善物品信息");
    activeWorkTab.value = "result";
    return;
  }
  if (!validateRequiredKeyPoints()) {
    activeWorkTab.value = "result";
    return;
  }
  if (!zhongjianReportFiles.value.length) {
    ElMessage.warning("请至少上传 1 个中检报告文件");
    return;
  }
  const qrInput = await promptPublishMaterialTagInput();
  if (!qrInput) {
    return;
  }

  zhongjianReportSubmitting.value = true;
  try {
    const response = await adminApi.saveZhongjianAppraisalReport({
      id: detail.value.task_info.id,
      zhongjian_report_no: zhongjianReportNo.value.trim(),
      product_info: normalizedProductForm(),
      result_text: resultForm.result_text.trim(),
      result_desc: resultForm.result_desc.trim(),
      attachments: resultAttachments.value,
      key_points: normalizedKeyPoints(),
      report_files: zhongjianReportFiles.value,
      qr_input: qrInput,
    });
    ElMessage.success(response.message || "验真吊牌已绑定，报告已发布");
    await loadDetail(detail.value.task_info.id);
    await fetchTasks();
  } catch (error: any) {
    console.error(error);
    ElMessage.error(error?.message || "中检报告录入失败");
  } finally {
    zhongjianReportSubmitting.value = false;
  }
}

function addSupplementItem() {
  supplementForm.items.push({
    item_name: "",
    guide_text: "",
    is_required: true,
  });
}

function removeSupplementItem(index: number) {
  if (supplementForm.items.length === 1) {
    supplementForm.items[0].item_name = "";
    supplementForm.items[0].guide_text = "";
    supplementForm.items[0].is_required = true;
    return;
  }
  supplementForm.items.splice(index, 1);
}

async function requestSupplement() {
  if (!detail.value) return;
  if (detail.value.task_info.status === "completed") {
    ElMessage.warning("当前任务已完成，不能再发起补资料");
    return;
  }

  const validItems = supplementForm.items.filter((item) => item.item_name.trim());
  if (!supplementForm.reason.trim()) {
    ElMessage.warning("请先填写补资料原因");
    return;
  }
  if (!validItems.length) {
    ElMessage.warning("请至少填写一项补资料要求");
    return;
  }

  supplementSubmitting.value = true;
  try {
    const response = await adminApi.requestAppraisalTaskSupplement({
      id: detail.value.task_info.id,
      reason: supplementForm.reason,
      deadline: supplementForm.deadline,
      items: validItems.map((item) => ({
        item_name: item.item_name.trim(),
        guide_text: item.guide_text.trim(),
        is_required: item.is_required,
      })),
    });
    ElMessage.success(response.message || "已发起补资料要求");
    await loadDetail(detail.value.task_info.id);
    await fetchTasks();
  } catch (error) {
    console.error(error);
    ElMessage.error("发起补资料失败");
  } finally {
    supplementSubmitting.value = false;
  }
}

function resetWorkbenchScroll() {
  nextTick(() => {
    workbenchAsideRef.value?.scrollTo({ top: 0, behavior: "auto" });
  });
}

watch(detailTab, (value) => {
  if (value === "actions") {
    resetWorkbenchScroll();
  }
});

watch(activeWorkTab, () => {
  if (detailTab.value === "actions") {
    resetWorkbenchScroll();
  }
});

onMounted(async () => {
  await Promise.all([fetchTasks(), fetchCategories()]);
});
</script>

<template>
  <el-card class="panel-card appraisal-scan-card" shadow="never">
    <div class="appraisal-scan">
      <div class="appraisal-scan__main">
        <div class="appraisal-scan__title">鉴定作业台扫码入口</div>
        <div class="appraisal-scan__desc">扫描内部流转挂牌后自动打开对应鉴定任务。</div>
      </div>
      <div class="appraisal-scan__control">
        <el-input
          v-model="transferTagNo"
          size="large"
          placeholder="扫描内部流转码"
          clearable
          @keyup.enter="scanTransferTag"
        >
          <template #append>
            <el-button :loading="transferScanLoading" @click="scanTransferTag">打开任务</el-button>
          </template>
        </el-input>
      </div>
    </div>
  </el-card>

  <el-card class="panel-card" shadow="never">
    <div class="filters-row">
      <el-input v-model="keyword" placeholder="搜索订单号 / 外部订单号 / 商品名称" clearable style="width: 340px" />
      <el-select v-model="taskStage" placeholder="任务阶段" style="width: 150px">
        <el-option v-for="item in stageOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <el-select v-model="status" placeholder="任务状态" style="width: 150px">
        <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <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-button type="primary" @click="fetchTasks">查询</el-button>
    </div>
  </el-card>

  <el-card class="panel-card orders-table" shadow="never">
    <el-table v-loading="loading" :data="tasks" stripe>
      <el-table-column prop="order_no" label="订单号" min-width="170" />
      <el-table-column prop="external_order_no" label="外部订单号" min-width="170" />
      <el-table-column prop="appraisal_no" label="鉴定单号" min-width="170" />
      <el-table-column prop="product_name" label="商品名称" min-width="210" />
      <el-table-column label="阶段进度" min-width="220">
        <template #default="{ row }">
          <div class="task-stage-progress">
            <div
              v-for="stage in row.stage_tasks"
              :key="`list-stage-${stage.id}`"
              class="task-stage-progress__item"
              :class="{ 'is-current': stage.is_current }"
            >
              <span class="task-stage-progress__name">{{ stage.task_stage_text }}</span>
              <OrderStatusTag :status="stage.status_text" />
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="任务状态" min-width="120">
        <template #default="{ row }">
          <OrderStatusTag :status="row.status_text" />
        </template>
      </el-table-column>
      <el-table-column prop="service_provider_text" label="服务类型" min-width="120" />
      <el-table-column prop="assignee_name" label="处理人" min-width="120" />
      <el-table-column prop="result_text" label="结论摘要" min-width="120" />
      <el-table-column prop="sla_deadline" label="SLA 截止" min-width="170" />
      <el-table-column label="操作" fixed="right" width="110">
        <template #default="{ row }">
          <el-button link type="primary" @click="openDetail(row)">查看详情</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>

  <el-drawer v-model="drawerVisible" size="76%" title="鉴定任务详情" class="task-detail-drawer">
    <div v-loading="detailLoading" v-if="detail" class="task-detail-shell">
      <div class="detail-card task-hero">
        <div class="task-hero__main">
          <div class="task-hero__eyebrow">鉴定任务工作区</div>
          <div class="task-hero__title">{{ productTitle }}</div>
          <div class="task-hero__meta">{{ productMetaText }}</div>
        </div>
        <div class="task-hero__side">
          <div class="task-hero__tags">
            <span class="task-stage-chip">{{ detail.task_info.task_stage_text }}</span>
            <OrderStatusTag :status="detail.task_info.status_text" />
            <span class="task-stage-chip task-stage-chip--warm">{{ detail.task_info.service_provider_text }}</span>
          </div>
          <div class="task-hero__summary">
            当前结论：<strong>{{ currentResultLabel }}</strong>
          </div>
        </div>
      </div>

      <div class="task-detail-toolbar">
        <div class="task-detail-toolbar__tabs">
          <button
            v-for="item in detailTabOptions"
            :key="item.value"
            type="button"
            class="task-detail-toolbar__tab"
            :class="{ 'is-active': detailTab === item.value }"
            @click="detailTab = item.value"
          >
            {{ item.label }}
          </button>
        </div>

        <div class="task-detail-toolbar__actions">
          <template v-if="detailTab === 'actions'">
            <template v-if="isTaskReadonly">
              <span class="task-detail-toolbar__readonly">{{ reportDraftHint || "当前任务已完成，仅支持查看。" }}</span>
            </template>
            <template v-else-if="activeWorkTab === 'result'">
              <el-button plain @click="openAssigneeDialog">分配处理人</el-button>
              <el-button v-if="canClaimTask" plain type="primary" :loading="assigneeSubmitting" @click="claimTask">认领给我</el-button>
              <el-button @click="resetResultForm">重置内容</el-button>
              <el-button type="warning" plain @click="openSupplementWorkbench">请求补资料</el-button>
              <el-button :loading="resultSubmitting" @click="submitResult('save')">保存结论</el-button>
              <el-button type="primary" :loading="resultSubmitting" @click="submitResult('submit')">提交结论</el-button>
            </template>
            <template v-else-if="activeWorkTab === 'zhongjian'">
              <el-button plain @click="openAssigneeDialog">分配处理人</el-button>
              <el-button v-if="canClaimTask" plain type="primary" :loading="assigneeSubmitting" @click="claimTask">认领给我</el-button>
              <el-button @click="resetZhongjianReportForm">重置内容</el-button>
              <el-button type="primary" :loading="zhongjianReportSubmitting" @click="submitZhongjianReport">提交并发布报告</el-button>
            </template>
            <template v-else>
              <el-button plain @click="returnToResultWorkbench">返回结论操作</el-button>
              <el-button @click="resetSupplementForm">重置</el-button>
              <el-button type="warning" :disabled="!canRequestSupplement" :loading="supplementSubmitting" @click="requestSupplement">
                发起补资料
              </el-button>
            </template>
          </template>
        </div>
      </div>

      <el-tabs v-model="detailTab" class="task-detail-tabs">
        <el-tab-pane label="任务信息" name="overview">
          <div class="task-overview-grid">
            <div class="detail-card task-panel task-panel--full">
              <div class="detail-card__title">鉴定工单总览</div>
              <div class="task-panel__desc">当前订单按单次鉴定处理，提交结论后直接生成报告草稿。</div>
              <div class="task-stage-overview">
                <div
                  v-for="stage in detail.stage_tasks"
                  :key="`detail-stage-${stage.id}`"
                  class="task-stage-card"
                  :class="{ 'is-current': stage.is_current }"
                >
                  <div class="task-stage-card__header">
                    <span class="task-stage-chip">{{ stage.task_stage_text }}</span>
                    <OrderStatusTag :status="stage.status_text" />
                  </div>
                  <div class="task-stage-card__meta">处理人：{{ stage.assignee_name }}</div>
                  <div class="task-stage-card__meta">结论：{{ stage.result_text || "暂未填写" }}</div>
                  <div class="task-stage-card__meta">提交时间：{{ stage.submitted_at || "-" }}</div>
                </div>
              </div>
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">任务概览</div>
              <div class="task-info-grid">
                <div class="task-info-item">
                  <div class="task-info-item__label">订单号</div>
                  <div class="task-info-item__value">{{ detail.task_info.order_no }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">鉴定单号</div>
                  <div class="task-info-item__value">{{ detail.task_info.appraisal_no }}</div>
                </div>
                <div v-if="detail.task_info.external_order_no" class="task-info-item">
                  <div class="task-info-item__label">外部订单号</div>
                  <div class="task-info-item__value">{{ detail.task_info.external_order_no }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">任务阶段 / 状态</div>
                  <div class="task-info-item__value task-info-item__value--inline">
                    <span class="task-stage-chip">{{ detail.task_info.task_stage_text }}</span>
                    <OrderStatusTag :status="detail.task_info.status_text" />
                  </div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">处理人</div>
                  <div class="task-info-item__value">{{ detail.task_info.assignee_name }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">服务类型</div>
                  <div class="task-info-item__value">{{ detail.task_info.service_provider_text }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">SLA 截止</div>
                  <div class="task-info-item__value">{{ detail.task_info.sla_deadline || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">开始时间</div>
                  <div class="task-info-item__value">{{ detail.task_info.started_at || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">提交时间</div>
                  <div class="task-info-item__value">{{ detail.task_info.submitted_at || "-" }}</div>
                </div>
              </div>
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">商品与送检</div>
              <div class="task-info-grid">
                <div class="task-info-item">
                  <div class="task-info-item__label">商品名称</div>
                  <div class="task-info-item__value">{{ detail.product_info.product_name || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">品类 / 品牌</div>
                  <div class="task-info-item__value">{{ detail.product_info.category_name || "-" }} / {{ detail.product_info.brand_name || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">颜色 / 规格</div>
                  <div class="task-info-item__value">{{ detail.product_info.color || "-" }} / {{ detail.product_info.size_spec || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">购买渠道</div>
                  <div class="task-info-item__value">{{ detail.extra_info.purchase_channel || "-" }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">购买价格</div>
                  <div class="task-info-item__value">¥{{ detail.extra_info.purchase_price }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">使用情况</div>
                  <div class="task-info-item__value">{{ usageStatusText }}</div>
                </div>
                <div class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">补充描述</div>
                  <div class="task-info-item__value">{{ detail.extra_info.condition_desc || detail.extra_info.remark || "-" }}</div>
                </div>
              </div>
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">当前结论</div>
              <div class="task-info-grid">
                <div class="task-info-item">
                  <div class="task-info-item__label">鉴定结论</div>
                  <div class="task-info-item__value">{{ currentResultLabel }}</div>
                </div>
                <div v-if="detail.result_info.key_points.length" class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">模板填写项</div>
                  <div class="task-pill-list">
                    <span v-for="item in detail.result_info.key_points" :key="item.point_code" class="task-pill">
                      {{ item.point_name }}：{{ item.point_value || "-" }}
                    </span>
                  </div>
                </div>
                <div class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">鉴定结论补充</div>
                  <div class="task-info-item__value">{{ detail.result_info.result_desc || "-" }}</div>
                </div>
                <div v-if="detail.report_summary" class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">关联报告草稿</div>
                  <div class="task-info-item__value">{{ detail.report_summary.report_no }} / {{ detail.report_summary.report_status_text }}</div>
                </div>
                <div class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">绑定吊牌</div>
                  <div v-if="detail.material_tag" class="task-info-item__value">
                    {{ detail.material_tag.verify_code }} / {{ detail.material_tag.bind_status_text }} / 扫码 {{ detail.material_tag.scan_count }} / 验真 {{ detail.material_tag.verify_count }}
                  </div>
                  <div v-else class="task-info-item__value">未绑定</div>
                </div>
              </div>
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">补资料状态</div>
              <div v-if="detail.supplement_task" class="task-info-grid">
                <div class="task-info-item">
                  <div class="task-info-item__label">当前状态</div>
                  <div class="task-info-item__value">{{ supplementStatusText }}</div>
                </div>
                <div class="task-info-item">
                  <div class="task-info-item__label">补资料数量</div>
                  <div class="task-info-item__value">{{ detail.supplement_task.items.length }} 项</div>
                </div>
                <div class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">补资料原因</div>
                  <div class="task-info-item__value">{{ detail.supplement_task.reason }}</div>
                </div>
                <div class="task-info-item task-info-item--full">
                  <div class="task-info-item__label">资料要求</div>
                  <div class="task-pill-list">
                    <span v-for="item in detail.supplement_task.items" :key="item.item_name" class="task-pill">
                      {{ item.item_name }}{{ item.is_required ? " · 必传" : " · 选传" }}
                    </span>
                  </div>
                </div>
              </div>
              <div v-else class="task-empty">
                当前没有待处理补资料任务，若资料完整可直接进入结论处理路径。
              </div>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="资料与轨迹" name="materials">
          <div class="task-stream-stack">
            <div class="detail-card task-panel">
              <div class="detail-card__title">资料任务项</div>
              <div class="task-panel__desc">把资料核验放到单独分区，只在需要时查看，避免与处理动作混在一起。</div>
              <div v-if="detail.materials.length" class="task-material-grid">
                <div v-for="item in detail.materials" :key="`${item.item_name}-${item.source_type}`" class="task-material-card">
                  <div class="task-material-card__header">
                    <div>
                      <div class="task-material-card__title">{{ item.item_name }}</div>
                      <div class="task-material-card__meta">{{ formatMaterialSource(item.source_type) }}</div>
                    </div>
                    <OrderStatusTag :status="formatMaterialStatus(item.status)" />
                  </div>
                  <div v-if="item.files.length" class="task-thumb-grid">
                    <div
                      v-for="file in item.files"
                      :key="file.file_id"
                      class="admin-upload-thumb"
                      @click="previewFiles(item.files, file.file_url)"
                    >
                      <img :src="file.thumbnail_url" alt="上传资料" />
                    </div>
                  </div>
                  <div v-else class="task-empty task-empty--compact">当前还没有上传文件</div>
                </div>
              </div>
              <el-empty v-else description="暂无资料任务项" />
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">订单时间轴</div>
              <div class="timeline-list task-timeline-list">
                <div v-for="item in detail.timeline" :key="`${item.node_text}-${item.occurred_at}`" class="timeline-node">
                  <div class="timeline-node__title">{{ item.node_text }}</div>
                  <div class="timeline-node__time">{{ item.occurred_at }}</div>
                  <div class="timeline-node__desc">{{ item.node_desc }}</div>
                </div>
              </div>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="处理工作台" name="actions">
          <div class="task-workbench-grid">
            <div ref="workbenchAsideRef" class="detail-card task-panel task-workbench-aside">
              <div class="task-context-card">
                <div class="task-context-card__header">
                  <div>
                    <div class="task-context-card__title">检测物品信息</div>
                    <div class="task-context-card__meta">{{ detail.task_info.service_provider_text }} / {{ detail.task_info.task_stage_text }}</div>
                  </div>
                  <OrderStatusTag :status="detail.task_info.status_text" />
                </div>

                <div class="task-context-list">
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">商品名称</div>
                    <div class="task-context-list__value">{{ detail.product_info.product_name || "-" }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">品类 / 品牌</div>
                    <div class="task-context-list__value">{{ detail.product_info.category_name || "-" }} / {{ detail.product_info.brand_name || "-" }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">颜色 / 规格</div>
                    <div class="task-context-list__value">{{ detail.product_info.color || "-" }} / {{ detail.product_info.size_spec || "-" }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">购买渠道</div>
                    <div class="task-context-list__value">{{ detail.extra_info.purchase_channel || "-" }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">购买价格</div>
                    <div class="task-context-list__value">¥{{ detail.extra_info.purchase_price }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">使用情况</div>
                    <div class="task-context-list__value">{{ usageStatusText }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">当前结论</div>
                    <div class="task-context-list__value">{{ currentResultLabel }}</div>
                  </div>
                  <div class="task-context-list__item">
                    <div class="task-context-list__label">补资料状态</div>
                    <div class="task-context-list__value">{{ supplementStatusText }}</div>
                  </div>
                </div>
              </div>

              <div class="task-context-section">
                <div class="task-context-section__title">用户上传资料</div>
                <div class="task-context-section__meta">{{ detail.materials.length }} 项资料任务，直接在此核对缩略图</div>

                <div v-if="detail.materials.length" class="task-context-materials">
                  <div v-for="item in detail.materials" :key="`workbench-${item.item_name}-${item.source_type}`" class="task-context-material">
                    <div class="task-context-material__header">
                      <div>
                        <div class="task-context-material__title">{{ item.item_name }}</div>
                        <div class="task-context-material__meta">{{ formatMaterialSource(item.source_type) }}</div>
                      </div>
                      <OrderStatusTag :status="formatMaterialStatus(item.status)" />
                    </div>

                    <div v-if="item.files.length" class="task-thumb-grid task-thumb-grid--compact">
                      <div
                        v-for="file in item.files"
                        :key="`workbench-${file.file_id}`"
                        class="admin-upload-thumb"
                        @click="previewFiles(item.files, file.file_url)"
                      >
                        <img :src="file.thumbnail_url" alt="上传资料" />
                      </div>
                    </div>
                    <div v-else class="task-empty task-empty--compact">当前还没有上传文件</div>
                  </div>
                </div>
                <div v-else class="task-empty task-empty--compact">
                  当前暂无用户上传资料
                </div>
              </div>
            </div>

            <div class="detail-card task-panel">
              <div class="detail-card__title">执行操作</div>
              <div class="task-panel__desc">一次只保留一条操作链路，完成后再切换到其他动作。</div>
              <el-alert v-if="reviewPrefillHint" :title="reviewPrefillHint" type="info" :closable="false" show-icon style="margin-top: 14px;" />
              <el-alert v-if="isTaskReadonly" :title="reportDraftHint || '当前任务已完成，只允许查看结果，不允许继续编辑或提交。'" type="warning" :closable="false" show-icon style="margin-top: 14px;" />

              <el-tabs v-model="activeWorkTab" stretch class="task-work-tabs">
                <el-tab-pane label="填写结论" name="result">
                  <div :key="`result-${formRenderKey}`" class="task-form-stack">
                    <el-alert
                      v-if="isZhongjianTask"
                      title="中检订单请在中检报告录入页提交，提交时同样需要绑定验真吊牌。"
                      type="info"
                      :closable="false"
                      show-icon
                    />
                    <div class="task-form-block">
                      <div class="task-form-block__title">物品信息</div>
                      <div class="task-panel__desc">客户推送订单可能不带物品信息，请鉴定师根据实物和资料补全，报告草稿会使用这里的内容。</div>
                      <div class="task-form-grid">
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">商品名称</div>
                          <el-input v-model="productForm.product_name" :disabled="isTaskReadonly" placeholder="例如 LV Neverfull MM 手袋" />
                        </div>
                        <div class="task-form-field">
                          <div class="task-form-field__label">品类</div>
                          <el-select
                            v-model="productForm.category_id"
                            :disabled="isTaskReadonly"
                            filterable
                            clearable
                            style="width: 100%"
                            placeholder="请选择鉴定品类"
                            @change="handleProductCategoryChange"
                          >
                            <el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
                          </el-select>
                        </div>
                        <div class="task-form-field">
                          <div class="task-form-field__label">品牌</div>
                          <el-input v-model="productForm.brand_name" :disabled="isTaskReadonly" placeholder="例如 Louis Vuitton" />
                        </div>
                        <div class="task-form-field">
                          <div class="task-form-field__label">颜色</div>
                          <el-input v-model="productForm.color" :disabled="isTaskReadonly" placeholder="例如 棕色老花" />
                        </div>
                        <div class="task-form-field">
                          <div class="task-form-field__label">规格 / 尺寸</div>
                          <el-input v-model="productForm.size_spec" :disabled="isTaskReadonly" placeholder="例如 MM" />
                        </div>
                        <div class="task-form-field">
                          <div class="task-form-field__label">序列号 / 编码</div>
                          <el-input v-model="productForm.serial_no" :disabled="isTaskReadonly" placeholder="输入可识别编号" />
                        </div>
                      </div>
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">吊牌绑定</div>
                      <div class="task-panel__desc">提交结论或中检报告时扫描平台验真吊牌，绑定成功后发布报告。</div>
                      <div v-if="detail.material_tag" class="task-material-tag-bound">
                        <div class="task-info-grid">
                          <div class="task-info-item task-info-item--full">
                            <div class="task-info-item__label">二维码链接</div>
                            <div class="task-info-item__value" style="word-break: break-all;">{{ detail.material_tag.qr_url }}</div>
                          </div>
                          <div class="task-info-item">
                            <div class="task-info-item__label">验真编码</div>
                            <div class="task-info-item__value">{{ detail.material_tag.verify_code }}</div>
                          </div>
                          <div class="task-info-item">
                            <div class="task-info-item__label">扫码 / 验真次数</div>
                            <div class="task-info-item__value">{{ detail.material_tag.scan_count }} / {{ detail.material_tag.verify_count }}</div>
                          </div>
                          <div class="task-info-item">
                            <div class="task-info-item__label">绑定人</div>
                            <div class="task-info-item__value">{{ detail.material_tag.bound_by_name || "-" }}</div>
                          </div>
                          <div class="task-info-item">
                            <div class="task-info-item__label">绑定时间</div>
                            <div class="task-info-item__value">{{ detail.material_tag.bound_at || "-" }}</div>
                          </div>
                        </div>
                      </div>
                      <div v-else-if="detail.report_summary" class="task-form-grid">
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">吊牌二维码链接</div>
                          <el-input
                            v-model="materialTagInput"
                            :disabled="!canBindMaterialTag"
                            placeholder="请用扫描枪扫描吊牌二维码，或粘贴二维码内链接"
                            clearable
                            @keyup.enter="bindMaterialTag"
                          >
                            <template #append>
                              <el-button :loading="materialTagBinding" :disabled="!canBindMaterialTag" @click="bindMaterialTag">绑定</el-button>
                            </template>
                          </el-input>
                        </div>
                      </div>
                      <el-alert
                        v-else
                        title="提交鉴定结论生成报告草稿后，才能绑定实物吊牌。"
                        type="info"
                        :closable="false"
                        show-icon
                        style="margin-top: 12px;"
                      />
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">基础结论</div>
                      <el-alert
                        v-if="currentAppraisalTemplate"
                        :title="`已加载 ${productForm.category_name || '当前品类'} 鉴定模板`"
                        type="success"
                        :closable="false"
                        show-icon
                        style="margin: 12px 0;"
                      />
                      <el-alert
                        v-else-if="productForm.category_id"
                        title="正在加载或未能加载当前品类鉴定模板。"
                        type="warning"
                        :closable="false"
                        show-icon
                        style="margin: 12px 0;"
                      />
                      <div class="task-form-grid">
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">鉴定结论 <span class="task-form-field__required">必填</span></div>
                          <el-input
                            v-model="resultForm.result_text"
                            :disabled="isTaskReadonly"
                            type="textarea"
                            :rows="3"
                            placeholder="请输入鉴定结论"
                          />
                        </div>
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">鉴定结论补充</div>
                          <el-input v-model="resultForm.result_desc" :disabled="isTaskReadonly" type="textarea" :rows="3" placeholder="可补充鉴定依据、异常点或说明" />
                        </div>
                      </div>
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">鉴定模板填写</div>
                      <div class="task-panel__desc">
                        选择品类后自动加载对应模板，按关键项逐项填写检查结论和备注。
                      </div>
                      <div v-loading="appraisalTemplateLoading">
                        <div v-if="resultKeyPoints.length" class="task-key-point-list">
                          <div v-for="item in resultKeyPoints" :key="item.point_code" class="task-key-point-card">
                            <div class="task-key-point-card__header">
                              <div class="task-key-point-card__title">
                                {{ item.point_name }}
                                <span v-if="item.is_required" class="task-key-point-card__required">必填</span>
                              </div>
                              <div class="task-key-point-card__code">{{ item.point_code }}</div>
                            </div>
                            <div class="task-form-grid">
                              <div class="task-form-field task-form-field--full">
                                <div class="task-form-field__label">检查结果</div>
                                <el-select
                                  v-if="item.point_type === 'select'"
                                  v-model="item.point_value"
                                  :disabled="isTaskReadonly"
                                  filterable
                                  allow-create
                                  default-first-option
                                  style="width: 100%"
                                  placeholder="请选择或输入检查结果"
                                >
                                  <el-option v-for="option in item.options" :key="option" :label="option" :value="option" />
                                </el-select>
                                <el-radio-group v-else-if="item.point_type === 'boolean'" v-model="item.point_value" :disabled="isTaskReadonly">
                                  <el-radio-button label="符合">符合</el-radio-button>
                                  <el-radio-button label="不符合">不符合</el-radio-button>
                                  <el-radio-button label="存疑">存疑</el-radio-button>
                                </el-radio-group>
                                <el-input
                                  v-else-if="item.point_type === 'textarea'"
                                  v-model="item.point_value"
                                  :disabled="isTaskReadonly"
                                  type="textarea"
                                  :rows="3"
                                  placeholder="请输入检查结果"
                                />
                                <el-input v-else v-model="item.point_value" :disabled="isTaskReadonly" placeholder="请输入检查结果" />
                              </div>
                              <div class="task-form-field task-form-field--full">
                                <div class="task-form-field__label">备注</div>
                                <el-input v-model="item.point_remark" :disabled="isTaskReadonly" type="textarea" :rows="2" placeholder="可补充细节、依据或风险点" />
                              </div>
                            </div>
                          </div>
                        </div>
                        <div v-else class="task-empty task-empty--compact">
                          当前品类没有额外鉴定关键项，请填写固定鉴定结论并按需上传附件。
                        </div>
                      </div>
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">附件上传</div>
                      <div class="task-panel__desc">支持上传图片、视频、PDF，作为本次鉴定结论的附件保存到报告草稿。</div>
                      <input
                        ref="evidenceInputRef"
                        type="file"
                        multiple
                        accept="image/*,video/*,.pdf,application/pdf"
                        style="display: none"
                        @change="handleEvidenceFileSelect"
                      />
                      <div class="task-evidence-toolbar">
                        <el-button :disabled="isTaskReadonly" :loading="evidenceUploading" @click="triggerEvidenceUpload">上传附件</el-button>
                        <span class="task-evidence-hint">{{ resultAttachments.length }} 个附件</span>
                      </div>
                      <div v-if="resultAttachments.length" class="task-evidence-list">
                        <div v-for="attachment in resultAttachments" :key="attachment.file_id" class="task-evidence-card">
                          <div
                            class="task-evidence-card__preview"
                            :class="{ 'is-image': attachment.file_type === 'image' }"
                            @click="previewEvidence(attachment.file_url)"
                          >
                            <img v-if="attachment.file_type === 'image' && attachment.thumbnail_url" :src="attachment.thumbnail_url" :alt="attachment.name || '证据图片'" />
                            <div v-else class="task-evidence-card__filetype">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                          </div>
                          <div class="task-evidence-card__body">
                            <div class="task-evidence-card__name">{{ attachment.name || attachment.file_url }}</div>
                            <div class="task-evidence-card__meta">{{ evidenceTypeLabel(attachment.file_type) }}</div>
                            <div class="task-evidence-card__actions">
                              <el-button link type="primary" @click="previewEvidence(attachment.file_url)">查看</el-button>
                              <el-button v-if="!isTaskReadonly" link type="danger" @click="removeEvidenceAttachment(attachment.file_url)">删除</el-button>
                            </div>
                          </div>
                        </div>
                      </div>
                      <div v-else class="task-empty task-empty--compact">当前还没有上传附件</div>
                    </div>

                  </div>
                </el-tab-pane>

                <el-tab-pane v-if="isZhongjianTask" label="中检报告录入" name="zhongjian">
                  <div :key="`zhongjian-${formRenderKey}`" class="task-form-stack">
                    <el-alert
                      title="请先在“填写结论”中补全物品信息、鉴定结论和模板项，再提交中检报告编号和文件；绑定吊牌成功后才会发布报告。"
                      type="info"
                      :closable="false"
                      show-icon
                    />

                    <div class="task-form-block">
                      <div class="task-form-block__title">中检报告信息</div>
                      <div class="task-form-grid">
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">中检报告编号 <span class="task-form-field__required">必填</span></div>
                          <el-input
                            v-model="zhongjianReportNo"
                            :disabled="isTaskReadonly"
                            placeholder="扫描或输入中检报告编号"
                            clearable
                            @keyup.enter="submitZhongjianReport"
                          />
                        </div>
                        <div v-if="detail.zhongjian_report?.report_entry_admin_name" class="task-form-field">
                          <div class="task-form-field__label">报告录入人</div>
                          <div class="task-readonly-value">{{ detail.zhongjian_report.report_entry_admin_name }}</div>
                        </div>
                        <div v-if="detail.zhongjian_report?.report_entered_at" class="task-form-field">
                          <div class="task-form-field__label">录入时间</div>
                          <div class="task-readonly-value">{{ detail.zhongjian_report.report_entered_at }}</div>
                        </div>
                      </div>
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">报告文件</div>
                      <div class="task-panel__desc">至少上传 1 个中检报告文件，支持图片、视频或 PDF。</div>
                      <input
                        ref="zhongjianReportFileInputRef"
                        type="file"
                        multiple
                        accept="image/*,video/*,.pdf,application/pdf"
                        style="display: none"
                        @change="handleZhongjianReportFileSelect"
                      />
                      <div class="task-evidence-toolbar">
                        <el-button :disabled="isTaskReadonly" :loading="zhongjianReportUploading" @click="triggerZhongjianReportUpload">上传报告文件</el-button>
                        <span class="task-evidence-hint">{{ zhongjianReportFiles.length }} 个文件</span>
                      </div>
                      <div v-if="zhongjianReportFiles.length" class="task-evidence-list">
                        <div v-for="file in zhongjianReportFiles" :key="file.file_id" class="task-evidence-card">
                          <div
                            class="task-evidence-card__preview"
                            :class="{ 'is-image': file.file_type === 'image' }"
                            @click="previewEvidence(file.file_url)"
                          >
                            <img v-if="file.file_type === 'image' && file.thumbnail_url" :src="file.thumbnail_url" :alt="file.name || '中检报告'" />
                            <div v-else class="task-evidence-card__filetype">{{ evidenceTypeLabel(file.file_type) }}</div>
                          </div>
                          <div class="task-evidence-card__body">
                            <div class="task-evidence-card__name">{{ file.name || file.file_url }}</div>
                            <div class="task-evidence-card__meta">{{ evidenceTypeLabel(file.file_type) }}</div>
                            <div class="task-evidence-card__actions">
                              <el-button link type="primary" @click="previewEvidence(file.file_url)">查看</el-button>
                              <el-button v-if="!isTaskReadonly" link type="danger" @click="removeZhongjianReportFile(file.file_url)">删除</el-button>
                            </div>
                          </div>
                        </div>
                      </div>
                      <div v-else class="task-empty task-empty--compact">当前还没有上传中检报告文件</div>
                    </div>
                  </div>
                </el-tab-pane>

                <el-tab-pane label="发起补资料" name="supplement" :disabled="isTaskReadonly">
                  <div :key="`supplement-${formRenderKey}`" class="task-form-stack">
                    <el-alert
                      v-if="detail.supplement_task"
                      title="当前已存在待处理补资料任务"
                      :description="`重新发起后会关闭任务 #${detail.supplement_task.id}，并以本次要求替换。`"
                      type="warning"
                      :closable="false"
                      show-icon
                    />

                    <div class="task-form-block">
                      <div class="task-form-block__title">触发说明</div>
                      <div class="task-form-grid">
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">补资料原因</div>
                          <el-input v-model="supplementForm.reason" :disabled="isTaskReadonly" type="textarea" :rows="3" placeholder="请输入需要用户补充资料的原因" />
                        </div>
                        <div class="task-form-field task-form-field--full">
                          <div class="task-form-field__label">截止时间</div>
                          <el-date-picker
                            v-model="supplementForm.deadline"
                            :disabled="isTaskReadonly"
                            type="datetime"
                            value-format="YYYY-MM-DD HH:mm:ss"
                            format="YYYY-MM-DD HH:mm"
                            placeholder="选择补资料截止时间"
                            style="width: 100%"
                          />
                        </div>
                      </div>
                    </div>

                    <div class="task-form-block">
                      <div class="task-form-block__title">补资料项</div>
                      <div class="task-supplement-list">
                        <div v-for="(item, index) in supplementForm.items" :key="`supplement-${index}`" class="task-supplement-item">
                          <div class="task-supplement-item__head">
                            <el-input v-model="item.item_name" :disabled="isTaskReadonly" placeholder="资料项名称，如 编码标签近照" />
                            <el-switch v-model="item.is_required" :disabled="isTaskReadonly" inline-prompt active-text="必传" inactive-text="选传" />
                            <el-button link type="danger" :disabled="isTaskReadonly" @click="removeSupplementItem(index)">删除</el-button>
                          </div>
                          <el-input
                            v-model="item.guide_text"
                            :disabled="isTaskReadonly"
                            type="textarea"
                            :rows="2"
                            placeholder="输入对用户的拍摄或补充指引"
                          />
                        </div>
                      </div>
                      <div class="task-supplement-actions">
                        <el-button plain :disabled="isTaskReadonly" @click="addSupplementItem">新增资料项</el-button>
                      </div>
                    </div>

                  </div>
                </el-tab-pane>
              </el-tabs>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </el-drawer>

  <el-dialog v-model="assigneeDialogVisible" title="分配处理人" width="560px">
    <div v-loading="assigneeOptionsLoading" style="display: grid; gap: 14px;">
      <div
        v-for="item in assigneeOptions"
        :key="item.id"
        :style="{
          border: selectedAssigneeId === item.id ? '1px solid #c8a45d' : '1px solid var(--admin-border)',
          borderRadius: '14px',
          padding: '16px 18px',
          cursor: 'pointer',
          background: selectedAssigneeId === item.id ? 'rgba(200, 164, 93, 0.08)' : '#fff',
        }"
        @click="selectedAssigneeId = item.id"
      >
        <div style="display:flex; justify-content:space-between; gap: 16px; align-items:center;">
          <div style="font-weight:700;">{{ item.name }}</div>
          <div style="color: var(--admin-text-subtle);">{{ item.mobile }}</div>
        </div>
        <div style="margin-top: 8px; color: var(--admin-text-subtle);">{{ item.role_names.join(' / ') || '未分配角色' }}</div>
      </div>
    </div>
    <template #footer>
      <el-button @click="assigneeDialogVisible = false">取消</el-button>
      <el-button type="primary" :loading="assigneeSubmitting" @click="submitAssigneeAssign">确认分配</el-button>
    </template>
  </el-dialog>

</template>

<style scoped>
.appraisal-scan-card {
  margin-bottom: 18px;
}

.appraisal-scan {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) minmax(320px, 520px);
  gap: 18px;
  align-items: center;
}

.appraisal-scan__title {
  color: var(--admin-text-main);
  font-size: 18px;
  font-weight: 800;
  line-height: 1.3;
}

.appraisal-scan__desc {
  margin-top: 6px;
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.6;
}

.appraisal-scan__control {
  min-width: 0;
}

:deep(.task-detail-drawer .el-drawer__body) {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  padding-top: 0;
}

.task-detail-shell {
  display: flex;
  flex-direction: column;
  gap: 18px;
  height: 100%;
  min-height: 0;
}

.task-hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 24px;
  background:
    radial-gradient(circle at top right, rgba(200, 164, 93, 0.12), transparent 30%),
    linear-gradient(135deg, #fffdfa 0%, #fbf8f1 100%);
}

.task-hero__main {
  min-width: 0;
}

.task-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 12px;
  border-radius: 999px;
  background: rgba(200, 164, 93, 0.12);
  color: #7a5a21;
  font-size: 12px;
  font-weight: 700;
}

.task-hero__title {
  margin-top: 14px;
  font-size: 28px;
  font-weight: 800;
  line-height: 1.2;
  color: var(--admin-text-main);
  word-break: break-word;
}

.task-hero__meta {
  margin-top: 10px;
  color: var(--admin-text-subtle);
  font-size: 14px;
  line-height: 1.6;
}

.task-hero__side {
  min-width: 280px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 14px;
}

.task-hero__tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
}

.task-hero__summary {
  color: var(--admin-text-subtle);
  font-size: 13px;
  text-align: right;
}

.task-stage-chip {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 12px;
  border-radius: 999px;
  background: rgba(72, 104, 133, 0.1);
  color: var(--admin-progress);
  font-size: 12px;
  font-weight: 700;
}

.task-stage-chip--warm {
  background: rgba(200, 164, 93, 0.14);
  color: #8b6327;
}

.task-detail-toolbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(233, 226, 210, 0.92);
  background: #fff;
  z-index: 3;
}

.task-detail-toolbar__tabs {
  display: flex;
  align-items: flex-end;
  gap: 28px;
}

.task-detail-toolbar__tab {
  position: relative;
  padding: 0 0 12px;
  border: none;
  background: transparent;
  color: var(--admin-text-main);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}

.task-detail-toolbar__tab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -7px;
  height: 3px;
  border-radius: 999px;
  background: transparent;
  transition: background-color 0.2s ease;
}

.task-detail-toolbar__tab.is-active {
  color: #409eff;
}

.task-detail-toolbar__tab.is-active::after {
  background: #409eff;
}

.task-detail-toolbar__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  min-height: 40px;
  min-width: 220px;
}

.task-detail-toolbar__readonly {
  color: var(--admin-text-subtle);
  font-size: 13px;
  font-weight: 600;
}

.task-detail-tabs {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.task-detail-tabs :deep(.el-tabs__header) {
  display: none;
  margin: 0;
}

.task-detail-tabs :deep(.el-tabs__content) {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-top: 18px;
  padding-right: 2px;
}

.task-detail-tabs :deep(.el-tabs__content::-webkit-scrollbar) {
  width: 8px;
}

.task-detail-tabs :deep(.el-tabs__content::-webkit-scrollbar-thumb) {
  border-radius: 999px;
  background: rgba(200, 164, 93, 0.24);
}

.task-overview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}

.task-panel {
  padding: 20px;
}

.task-panel--full {
  grid-column: 1 / -1;
}

.task-panel__desc {
  margin-top: 8px;
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.6;
}

.task-info-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 16px;
}

.task-info-item {
  padding: 14px 16px;
  border: 1px solid #efe8d9;
  border-radius: 16px;
  background: #fcfaf5;
}

.task-info-item--full {
  grid-column: 1 / -1;
}

.task-info-item__label {
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-info-item__value {
  margin-top: 8px;
  color: var(--admin-text-main);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.5;
  word-break: break-word;
}

.task-info-item__value--inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.task-pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.task-pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border-radius: 999px;
  background: rgba(72, 104, 133, 0.08);
  color: var(--admin-progress);
  font-size: 12px;
  font-weight: 600;
}

.task-stage-progress {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.task-stage-progress__item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.task-stage-progress__item.is-current .task-stage-progress__name {
  color: var(--admin-text-main);
}

.task-stage-progress__name {
  min-width: 34px;
  color: var(--admin-text-subtle);
  font-size: 12px;
  font-weight: 700;
}

.task-stage-overview {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 16px;
}

.task-stage-card {
  padding: 16px;
  border: 1px solid #efe8d9;
  border-radius: 18px;
  background: #fcfaf5;
}

.task-stage-card.is-current {
  box-shadow:
    inset 0 0 0 1px rgba(72, 104, 133, 0.14),
    0 10px 22px rgba(72, 104, 133, 0.08);
}

.task-stage-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.task-stage-card__meta {
  margin-top: 10px;
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.6;
}

.task-empty {
  margin-top: 16px;
  padding: 18px;
  border-radius: 16px;
  background: #fcfaf5;
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.7;
}

.task-empty--compact {
  margin-top: 12px;
  padding: 14px;
}

.task-key-point-list {
  display: grid;
  gap: 14px;
  margin-top: 14px;
}

.task-key-point-card {
  padding: 16px;
  border: 1px solid #efe8d9;
  border-radius: 18px;
  background: #fcfaf5;
}

.task-key-point-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 12px;
}

.task-key-point-card__title {
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
}

.task-key-point-card__required {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  margin-left: 8px;
  padding: 0 8px;
  border-radius: 999px;
  background: rgba(182, 122, 45, 0.12);
  color: var(--admin-warning);
  font-size: 12px;
}

.task-key-point-card__code {
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-stream-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.task-material-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.task-material-card {
  padding: 16px;
  border: 1px solid #efe8d9;
  border-radius: 18px;
  background: #fcfaf5;
}

.task-material-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.task-material-card__title {
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
}

.task-material-card__meta {
  margin-top: 6px;
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-thumb-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}

.task-thumb-grid--compact {
  margin-top: 12px;
}

.task-timeline-list {
  margin-top: 16px;
}

.task-workbench-grid {
  display: grid;
  grid-template-columns: minmax(340px, 420px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.task-workbench-aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: sticky;
  top: 0;
  align-self: start;
  max-height: calc(100vh - 210px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
}

.task-workbench-aside::-webkit-scrollbar {
  width: 8px;
}

.task-workbench-aside::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: rgba(200, 164, 93, 0.26);
}

.task-workbench-aside::-webkit-scrollbar-track {
  background: transparent;
}

.task-context-card {
  padding: 16px;
  border: 1px solid #efe8d9;
  border-radius: 18px;
  background: #fcfaf5;
}

.task-context-section {
  padding: 2px 0 0;
}

.task-context-section__title {
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.4;
}

.task-context-section__meta {
  margin-top: 8px;
  color: var(--admin-text-subtle);
  font-size: 12px;
  line-height: 1.6;
}

.task-context-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.task-context-card__title {
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
}

.task-context-card__meta {
  margin-top: 6px;
  color: var(--admin-text-subtle);
  font-size: 12px;
  line-height: 1.6;
}

.task-context-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-top: 14px;
}

.task-context-list__item {
  padding: 12px 14px;
  border-radius: 14px;
  background: #ffffff;
  border: 1px solid rgba(239, 232, 217, 0.95);
}

.task-context-list__label {
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-context-list__value {
  margin-top: 8px;
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.5;
  word-break: break-word;
}

.task-context-materials {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 14px;
}

.task-context-material {
  padding: 14px;
  border-radius: 16px;
  background: #ffffff;
  border: 1px solid rgba(239, 232, 217, 0.95);
}

.task-context-material__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.task-context-material__title {
  color: var(--admin-text-main);
  font-size: 14px;
  font-weight: 700;
}

.task-context-material__meta {
  margin-top: 6px;
  color: var(--admin-text-subtle);
  font-size: 12px;
  line-height: 1.6;
}

.task-note-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
  color: var(--admin-text-subtle);
  font-size: 13px;
  line-height: 1.6;
}

.task-work-tabs :deep(.el-tabs__header) {
  margin: 0 0 18px;
}

.task-form-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.task-form-block {
  padding: 18px;
  border: 1px solid #efe8d9;
  border-radius: 18px;
  background: #fcfaf5;
}

.task-form-block__title {
  color: var(--admin-text-main);
  font-size: 15px;
  font-weight: 700;
}

.task-material-tag-bound {
  margin-top: 12px;
}

.task-evidence-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
}

.task-evidence-hint {
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-evidence-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
}

.task-evidence-card {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 14px;
  padding: 14px;
  border-radius: 16px;
  background: #ffffff;
  border: 1px solid rgba(239, 232, 217, 0.95);
}

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

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

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

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

.task-evidence-card__name {
  color: var(--admin-text-main);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  word-break: break-word;
}

.task-evidence-card__meta {
  margin-top: 6px;
  color: var(--admin-text-subtle);
  font-size: 12px;
}

.task-evidence-card__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
}

.task-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.task-form-field--full {
  grid-column: 1 / -1;
}

.task-form-field__label {
  margin-bottom: 8px;
  color: var(--admin-text-subtle);
  font-size: 13px;
}

.task-form-field__required {
  margin-left: 6px;
  color: #c2410c;
  font-size: 12px;
  font-weight: 600;
}

.task-readonly-value {
  min-height: 32px;
  padding: 7px 0;
  color: var(--admin-text-main);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  word-break: break-word;
}

.task-form-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.task-supplement-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
}

.task-supplement-item {
  padding: 14px;
  border: 1px solid rgba(233, 226, 210, 0.96);
  border-radius: 16px;
  background: #ffffff;
}

.task-supplement-item__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 12px;
}

.task-supplement-actions {
  margin-top: 12px;
}

@media (max-width: 1280px) {
  .task-hero,
  .task-workbench-grid {
    grid-template-columns: 1fr;
    display: grid;
  }

  .task-hero__side {
    min-width: 0;
    align-items: flex-start;
  }

  .task-workbench-aside {
    position: static;
    max-height: none;
    overflow: visible;
  }

  .task-detail-toolbar {
    align-items: stretch;
    flex-direction: column;
  }

  .task-detail-toolbar__tabs {
    gap: 18px;
    flex-wrap: wrap;
  }

  .task-detail-toolbar__actions {
    justify-content: flex-start;
    min-width: 0;
  }

  .task-hero__tags,
  .task-hero__summary {
    justify-content: flex-start;
    text-align: left;
  }
}

@media (max-width: 960px) {
  .appraisal-scan,
  .task-info-grid,
  .task-form-grid,
  .task-supplement-item__head {
    grid-template-columns: 1fr;
  }

  .task-evidence-card {
    grid-template-columns: 1fr;
  }
}
</style>
