<template>
  <el-dialog :model-value="modelValue" class="service-record-dialog" top="6vh" :close-on-click-modal="false"
    destroy-on-close @update:model-value="(v) => $emit('update:modelValue', v)" @open="onOpen">
    <div class="body-wrap">
      <div class="body-header">
        <span class="body-title">{{ title }} - {{ hospitalName }}</span>
        <img src="@/assets/image/close-btn.svg" alt="" class="close-btn" @click="closeDialog" />
      </div>

      <!-- 添加记录 -->
      <div class="section">
        <div class="border-title">
          添加{{ typeLabel }}记录
        </div>

        <!-- 电话回访 -->
        <template v-if="type === 'call'">
          <el-form class="service-form" ref="formRef" :model="form" :rules="rules" label-width="84px"
            label-position="right">
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="回访时间" prop="callTime">
                  <el-date-picker v-model="form.callTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
                    placeholder="年/月/日/时/分/秒" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="回访人" prop="callPerson">
                  <el-input v-model="form.callPerson" placeholder="请输入" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="回访内容" prop="content">
              <el-input v-model="form.content" type="textarea" :rows="4" placeholder="请输入回访情况" />
            </el-form-item>
          </el-form>
        </template>

        <!-- 现场巡检 -->
        <template v-else-if="type === 'inspection'">
          <el-form class="service-form" ref="formRef" :model="form" :rules="rules" label-width="84px"
            label-position="right">
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="巡检时间" prop="inspectionTime">
                  <el-date-picker v-model="form.inspectionTime" type="date" value-format="YYYY-MM-DD"
                    placeholder="年/月/日" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="巡检人" prop="inspectionPerson">
                  <el-input v-model="form.inspectionPerson" placeholder="请输入" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="巡检内容" prop="content">
              <el-input v-model="form.content" type="textarea" :rows="4" placeholder="请输入巡检内容" maxlength="1000"
                show-word-limit />
            </el-form-item>
            <el-form-item label="巡检报告">
              <el-upload class="upload-wrap" v-model:file-list="reportFileList" :auto-upload="false" :limit="1"
                :on-exceed="handleReportExceed" :on-change="handleReportChange" :on-remove="handleReportRemove">
                <div class="upload-btn">
                  <div class="left">+ 添加文件</div>
                  <div class="right">（不超过50M）</div>
                </div>
                <template #file="{ file }">
                  <div class="file-item">
                    <img class="file-icon" src="@/assets/image/admin/orders/file.svg" alt="">
                    <div class="file-name">&nbsp;&nbsp;{{ file.name }}</div>
                    <div class="file-size">&nbsp;&nbsp;{{ ((file.size || 0) / 1024 / 1024).toFixed(2) }}MB</div>
                    <div class="file-delete" @click="handleReportDelete(file)">删除</div>
                  </div>
                </template>
              </el-upload>
            </el-form-item>
          </el-form>
        </template>

        <!-- 培训记录 -->
        <template v-else-if="type === 'training'">
          <el-form class="service-form" ref="formRef" :model="form" :rules="rules" label-width="84px"
            label-position="right">
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="培训日期" prop="trainingDate">
                  <el-date-picker v-model="form.trainingDate" type="date" value-format="YYYY-MM-DD" placeholder="年/月/日"
                    style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="参与人数" prop="participants">
                  <el-input v-model="form.participants" type="number" placeholder="请输入参与人数" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="培训方式" prop="mode">
                  <el-radio-group v-model="form.trainingMethod">
                    <el-radio value="线上">线上</el-radio>
                    <el-radio value="线下">线下</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="培训人员" prop="trainer">
                  <el-input v-model="form.trainer" placeholder="请输入培训人员名称" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="培训主题" prop="topic">
              <el-input v-model="form.topic" placeholder="请输入" maxlength="200" />
            </el-form-item>
          </el-form>
        </template>

        <!-- 纪念品记录 -->
        <template v-else-if="type === 'gift'">
          <el-form class="service-form" ref="formRef" :model="form" :rules="rules" label-width="96px"
            label-position="right">
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="年份" prop="date">
                  <el-date-picker v-model="form.date" type="year" value-format="YYYY" placeholder=""
                    style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="数量" prop="quantity">
                  <el-input v-model="form.quantity" type="number" placeholder="请输入数量" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="纪念品名称" prop="name">
              <el-input v-model="form.name" placeholder="请输入纪念品名称" maxlength="200" />
            </el-form-item>
            <el-form-item label="快递单号" prop="trackingNo">
              <el-input v-model="form.trackingNo" placeholder="请填写快递单号" maxlength="100" style="max-width: 360px" />
            </el-form-item>
          </el-form>
        </template>

        <div class="form-footer">
          <el-button type="primary" :loading="submitting" @click="onSubmit">保存记录</el-button>
        </div>
      </div>

      <!-- 历史记录 -->
      <div class="section">
        <div class="border-title">
          历史记录
        </div>

        <div v-loading="loading" class="history-list">
          <el-empty v-if="!loading && historyList.length === 0" description="暂无记录" :image-size="80" />
          <div v-else class="history-items">
            <div v-for="(item, idx) in historyList" :key="item.id || idx" class="history-item">
              <div class="history-head">
                <span class="rec-no">记录 {{ idx + 1 }}</span>
                <span class="rec-time">{{ formatTime(item) }}</span>
              </div>
              <div class="history-body">
                <template v-if="type === 'call'">
                  <div class="row"><span class="lbl">回访人：</span>{{ item.callPerson }}</div>
                  <div class="row"><span class="lbl">回访情况：</span>{{ item.content || "—" }}</div>
                </template>
                <template v-else-if="type === 'inspection'">
                  <div class="row"><span class="lbl">巡检人：</span>{{ item.inspectionPerson }}</div>
                  <div class="row"><span class="lbl">巡检情况：</span>{{ item.content || "—" }}</div>
                  <div class="row" v-if="getInspectionFilePath(item)">
                    <span class="lbl">巡检报告：</span>
                    <img style="width: 18px;height: 18px;vertical-align: middle;margin-right: 4px;" src="@/assets/image/admin/orders/file.svg" alt="">
                    <span class="file" style="cursor:pointer;" @click="viewReport(getInspectionFilePath(item))">
                      {{ getInspectionFileName(item) }}
                    </span>
                  </div>
                </template>
                <template v-else-if="type === 'training'">
                  <div class="row"><span class="lbl">培训主题：</span>{{ item.topic }}</div>
                  <div class="row"><span class="lbl">参与人员：</span>{{ item.participants || "—" }}人</div>
                </template>
                <template v-else-if="type === 'gift'">
                  <div class="row"><span class="lbl">纪念品名称：</span>{{ item.name }}</div>
                  <div class="row"><span class="lbl">数量：</span>{{ item.quantity || "—" }}份</div>
                  <div class="row"><span class="lbl">记录时间：</span>{{ dayjs(item.createdAt).format('YYYY-MM-DD HH:mm') ||
                    "—" }}</div>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 巡检报告预览 -->
    <FilePreviewDialog :visible="previewVisible" :blob-url="previewUrl" :blob="previewBlob" :file-name="previewName"
      :file-type="previewType" @update:visible="(v) => (previewVisible = v)" @close="cleanupPreview"
      @download="onPreviewDownload" />
  </el-dialog>
</template>

<script setup>
import { computed, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import dayjs from "dayjs";
import {
  addAdminCall,
  addAdminGift,
  addAdminInspection,
  addAdminTraining,
  getAdminCalls,
  getAdminGifts,
  getAdminInspections,
  getAdminTrainings,
  getUploadFile,
} from "@/service/modular/admin";
import FilePreviewDialog from "@/components/FilePreviewDialog.vue";

const props = defineProps({
  modelValue: { type: Boolean, default: false },
  // call | inspection | training | gift
  type: { type: String, default: "call" },
  hospitalId: { type: [String, Number], default: "" },
  hospitalName: { type: String, default: "" },
});

const emit = defineEmits(["update:modelValue", "saved"]);

const formRef = ref();
const submitting = ref(false);
const loading = ref(false);
const historyList = ref([]);

// 巡检报告：仅现场巡检场景下使用，单文件
const reportFileList = ref([]);
const MAX_REPORT_FILE_SIZE = 50 * 1024 * 1024;

// 超出 limit 时仅保留最后一个
const handleReportExceed = (files) => {
  reportFileList.value = files.slice(-1);
};

// 选择文件时校验大小
const handleReportChange = (file) => {
  if (file?.size > MAX_REPORT_FILE_SIZE) {
    ElMessage.warning("文件不能超过 50MB");
    reportFileList.value = (reportFileList.value || []).filter(
      (f) => f.uid !== file.uid,
    );
  }
};

// el-upload 自带的删除回调，无需额外处理（v-model:file-list 会自动移除）
const handleReportRemove = () => { };

// 自定义"删除"按钮：按 uid 从 reportFileList 中移除
const handleReportDelete = (file) => {
  reportFileList.value = (reportFileList.value || []).filter(
    (f) => f.uid !== file?.uid,
  );
};

// 构造现场巡检的 FormData：表单字段 + files[]
const buildInspectionFormData = (data) => {
  const fd = new FormData();
  Object.entries(data || {}).forEach(([key, value]) => {
    if (value === undefined || value === null || value === "") return;
    fd.append(key, value);
  });
  // 仅追加用户新上传的真实文件（带 raw 的项）；编辑场景下若无文件则不携带 files 字段
  for (const f of reportFileList.value || []) {
    if (f.raw) fd.append("files", f.raw, f.name);
  }
  return fd;
};

const titleMap = {
  call: "电话回访记录",
  inspection: "现场巡检记录",
  training: "培训记录",
  gift: "纪念品记录",
};

const title = computed(() => titleMap[props.type] || "");
const typeLabel = computed(() => title.value.replace("记录", ""));

const defaultForm = () => {
  if (props.type === "call") {
    return { callTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), callPerson: "", content: "" };
  }
  if (props.type === "inspection") {
    return { inspectionTime: dayjs().format("YYYY-MM-DD"), inspectionPerson: "", content: "" };
  }
  if (props.type === "training") {
    return {
      trainingDate: dayjs().format("YYYY-MM-DD"),
      participants: "",
      trainingMethod: "线上",
      trainer: "",
      topic: "",
    };
  }
  // gift
  return { date: String(dayjs().format('YYYY-MM-DD')), quantity: "", name: "", trackingNo: "" };
};

const form = reactive(defaultForm());

const buildRules = () => {
  if (props.type === "call") {
    return {
      callTime: [{ required: true, message: "请选择回访时间", trigger: "change" }],
      callPerson: [{ required: true, message: "请输入回访人", trigger: "blur" }],
      content: [{ required: true, message: "请输入回访内容", trigger: "blur" }],
    };
  }
  if (props.type === "inspection") {
    return {
      inspectionTime: [{ required: true, message: "请选择巡检时间", trigger: "change" }],
      inspectionPerson: [{ required: true, message: "请输入巡检人", trigger: "blur" }],
      content: [{ required: true, message: "请输入巡检内容", trigger: "blur" }],
    };
  }
  if (props.type === "training") {
    return {
      trainingDate: [{ required: true, message: "请选择培训日期", trigger: "change" }],
      participants: [{ required: true, message: "请输入参与人数", trigger: "blur" }],
      topic: [{ required: true, message: "请输入培训主题", trigger: "blur" }],
    };
  }
  return {
    date: [{ required: true, message: "请选择日期", trigger: "change" }],
    name: [{ required: true, message: "请输入纪念品名称", trigger: "blur" }],
  };
};

const rules = buildRules();

const loadHistory = async () => {
  if (!props.hospitalId) {
    historyList.value = [];
    return;
  }
  loading.value = true;
  try {
    let res;
    if (props.type === "call") {
      res = await getAdminCalls(props.hospitalId, { page: 1, pageSize: 50 });
    } else if (props.type === "inspection") {
      res = await getAdminInspections(props.hospitalId);
    } else if (props.type === "training") {
      res = await getAdminTrainings(props.hospitalId);
    } else if (props.type === "gift") {
      res = await getAdminGifts(props.hospitalId);
    }
    historyList.value = res?.list || res || [];
  } finally {
    loading.value = false;
  }
};

const resetForm = () => {
  Object.assign(form, defaultForm());
};

const closeDialog = () => emit("update:modelValue", false);

const onOpen = () => {
  resetForm();
  reportFileList.value = [];
  loadHistory();
};

const formatTime = (item) => {
  if (props.type === "gift") {
    const t = item.date;
    return (dayjs(t).isValid() ? dayjs(t).format("YYYY") : "—") + '年';
  }

  if (props.type === "inspection") {
    const t = item.inspectionTime;
    return (dayjs(t).isValid() ? dayjs(t).format("YYYY-MM-DD HH:mm") : "—");
  }

  if (props.type === "training") {
    const t = item.trainingDate;
    return (dayjs(t).isValid() ? dayjs(t).format("YYYY-MM-DD HH:mm") : "—");
  }

  const t = item.callTime;
  if (!t) return "—";
  return dayjs(t).isValid() ? dayjs(t).format("YYYY-MM-DD HH:mm") : "—";
};

const onSubmit = async () => {
  if (!formRef.value) return;
  await formRef.value.validate(async (valid) => {
    if (!valid) return;
    if (!props.hospitalId) {
      ElMessage.error("缺少医院参数");
      return;
    }
    submitting.value = true;
    try {
      let payload;
      if (props.type === "call") payload = { ...form };
      else if (props.type === "inspection") payload = buildInspectionFormData({ ...form });
      else if (props.type === "training") payload = { ...form };
      else payload = { date: form.date, name: form.name, quantity: form.quantity };

      if (props.type === "call") {
        await addAdminCall(props.hospitalId, payload);
      } else if (props.type === "inspection") {
        await addAdminInspection(props.hospitalId, payload);
      } else if (props.type === "training") {
        await addAdminTraining(props.hospitalId, payload);
      } else if (props.type === "gift") {
        await addAdminGift(props.hospitalId, payload);
      }
      ElMessage.success("保存成功");
      emit("saved");
      loadHistory();
      resetForm();
    } finally {
      submitting.value = false;
    }
  });
};

// ============== 巡检报告预览/下载 ==============
const previewVisible = ref(false);
const previewUrl = ref("");
const previewBlob = ref(null);
const previewName = ref("");
const previewType = ref(""); // 'pdf' | 'image' | ''

const cleanupPreview = () => {
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value);
    previewUrl.value = "";
  }
  previewBlob.value = null;
  previewName.value = "";
  previewType.value = "";
};

// 从路径中提取最后的文件名（含扩展名）作为下载名
const getFileNameFromPath = (path) => {
  if (!path) return "";
  return String(path).replace(/\\/g, "/").split("/").filter(Boolean).pop() || "";
};

// 根据文件名/扩展名 + blob 的 mime 判断文件类型
const getFileType = (fileName, blob) => {
  const name = String(fileName || "");
  const ext = name.split(".").pop()?.toLowerCase() || "";
  const mime = blob?.type || "";
  if (ext === "pdf" || mime === "application/pdf") return "pdf";
  if (
    ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(ext) ||
    (mime && mime.startsWith("image/"))
  ) {
    return "image";
  }
  return "other";
};

// 浏览器直接下载 blob（指定文件名）
const downloadBlob = (blob, fileName) => {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName || "download";
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 0);
};

// FilePreviewDialog 下载按钮回调
const onPreviewDownload = ({ blob, fileName }) => {
  if (!blob) return;
  downloadBlob(blob, fileName);
};

// 安全解析后端返回的 filePaths 字段（JSON 字符串数组），解析失败返回 null
const parseFilePaths = (raw) => {
  if (!raw) return null;
  if (Array.isArray(raw)) return raw;
  try {
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed : null;
  } catch (_) {
    return null;
  }
};

// 取巡检记录的第一个文件路径（后端约定长度最大为 1），无则返回 ""
const getInspectionFilePath = (item) => {
  const list = parseFilePaths(item?.filePaths);
  return list && list.length ? list[0] : "";
};

// 取巡检记录的第一个文件显示名（从路径中截取最后一段）
const getInspectionFileName = (item) => {
  const p = getInspectionFilePath(item);
  return getFileNameFromPath(p) || p || "—";
};

// 点击文件名：PDF / 图片走预览弹窗，其他格式直接下载
const viewReport = async (filePath) => {
  if (!filePath) return;
  const path = String(filePath);
  const downloadName = getFileNameFromPath(path) || path;
  try {
    const blob = await getUploadFile(path);
    const type = getFileType(downloadName, blob);
    if (type === "pdf" || type === "image") {
      cleanupPreview();
      previewBlob.value = blob;
      previewUrl.value = URL.createObjectURL(blob);
      previewName.value = downloadName;
      previewType.value = type;
      previewVisible.value = true;
    } else {
      downloadBlob(blob, downloadName);
    }
  } catch (e) {
    ElMessage.error(e?.message || "文件加载失败");
  }
};
</script>

<style lang="scss">
.service-record-dialog {
  min-width: 800px;

  .section {
    .border-title {
      margin-bottom: 16px;
    }
  }

  .section+.section {
    margin-top: 32px;
  }

  .service-form {
    .el-form-item__label {
      font-weight: 400 !important;
      font-size: 14px !important;
      color: #1D2129 !important;
    }

    .el-input__wrapper {
      min-height: 48px;
      border-radius: 8px 8px 8px 8px;
      border: 1px solid #E0E0E0;
      box-shadow: none;
    }

    .el-textarea__inner {
      border-radius: 8px 8px 8px 8px;
      border: 1px solid #E0E0E0;
      box-shadow: none;
    }
  }

  .form-footer {
    margin-top: 4px;
    display: flex;
    justify-content: flex-end;
  }

  .history-list {
    min-height: 80px;
    max-height: 200px;
    overflow-y: auto;

    .history-items {
      display: flex;
      flex-direction: column;
      gap: 16px;
    }

    .history-item {
      width: 100%;
      background: #F8F8F8;
      border-radius: 12px 12px 12px 12px;
      padding: 12px;
    }

    .history-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 12px;

      .rec-no {
        font-weight: 600;
        font-size: 16px;
        color: #1D2129;
      }

      .rec-time {
        font-weight: 400;
        font-size: 14px;
        color: #666666;
      }
    }

    .history-body {
      .row {
        font-weight: 400;
        font-size: 14px;
        color: #1D2129;
        line-height: 1.5;

        .file {
          &:hover {
            color: #3289FB;
          }
        }

        .lbl {
          color: #666;
        }
      }
    }
  }

  // 巡检报告上传（与 admin 端统一风格）
  .upload-wrap {
    width: 100%;

    .el-upload-list__item {
      &:hover {
        background: transparent;
      }

      .file-item {
        display: flex;
        align-items: center;
        font-weight: 400;
        font-size: 14px;

        .file-icon {
          width: 18px;
          height: 18px;
        }

        .file-name,
        .file-delete {
          color: #1D2129;

          &:hover {
            color: #1890ff;
          }
        }

        .file-delete {
          margin-left: 14px;
          cursor: pointer;
        }

        .file-size {
          color: #BCBCBC;
        }
      }
    }
  }

  .upload-btn {
    display: flex;
    align-items: center;

    .left {
      font-weight: 400;
      font-size: 14px;
      color: #2B324C;
    }

    .right {
      font-weight: 400;
      font-size: 14px;
      color: #666666;
    }
  }

  // 强制上传按钮区域宽度铺满
  :deep(.el-form-item .el-form-item__content > .el-upload) {
    width: 100%;
  }
}
</style>
