<template>
  <my-layout v-loading="loading">
    <layout-item class="bg-white">
      <div class="relative">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="" name="init">
            <template #label>
              <div class="px-12px">待审核</div>
            </template>
          </el-tab-pane>
          <el-tab-pane label="已审核" name="audited">
            <template #label>
              <div class="px-12px">已审核</div>
            </template>
          </el-tab-pane>
        </el-tabs>
        <div class="absolute right-15px top-4px">
          <el-switch v-model="isOnline" inline-prompt active-text="在线" inactive-text="下线" size="default"
            style="--el-switch-on-color: #0074ff; --el-switch-off-color: #999" @change="toggleOnline($event)" />
        </div>

      </div>
      <div class="py-5px flex -mt-15px" @keyup.enter="search()">
        <expand-filter-box v-model:can-expand="canExpand" :enable-expand="true" class="flex-grow" :expand="expand">
          <check-box-filter v-model="doctorNos" label="医生" :list="doctors" />
          <input-filter v-model="name" label="患者姓名" placeholder="请输入患者姓名" :width="280" />
          <input-filter v-model="mobile" label="患者手机号" placeholder="请输入患者手机号" :width="280" />
        </expand-filter-box>
        <div class="flex-shrink-0 flex items-center h-40px pr-15px">
          <el-button v-if="canExpand" text plain @click="expand = !expand">
            <span class="mr-5px">{{ expand ? "收起筛选" : "更多筛选" }}</span>
            <el-icon v-if="expand">
              <ArrowUpBold />
            </el-icon>
            <el-icon v-else>
              <ArrowDownBold />
            </el-icon>
          </el-button>
          <el-button type="primary" @click="search">查询</el-button>
          <el-button plain @click="clear()">清空筛选</el-button>
        </div>
      </div>
    </layout-item>
    <Layout-item v-if="activeTab === 'init'" class="bg-white mt-10px">
      <div class="flex items-center px-15px py-12px text-14px">
        <div class="mr-15px flex-shrink-0">
          已选择处方：
          <span class="text-red-500">{{ selections.length }}</span>
        </div>
        <el-button class="flex-shrink-0" type="success" :icon="Select" @click="audit('PASS')">审核通过</el-button>
        <el-button plain class="flex-shrink-0" type="danger" :icon="CloseBold" @click="rejectRx">审核不通过</el-button>
        <div class="flex-grow mx-15px">
          <div v-if="refreshSubmitTime > latestTime"
            class="inline-block px-30px py-8px rounded text-red-500 bg-red-300 bg-opacity-30">
            <el-icon class="mr-5px transform translate-y-2px">
              <Warning />
            </el-icon>
            您有处方待审核， 请及时刷新查看!
          </div>
        </div>
        <!-- v-if="reUploadCount > 0" -->
        <el-badge :hidden="reUploadCount === 0" :value="reUploadCount" :max="99" class="item">
          <el-button class="flex-shrink-0" type="warning" @click="reuploadVisible = true">查看未上传处方</el-button>
        </el-badge>
        <el-button plain class="flex-shrink-0 ml-10px" type="primary" @click="search()">刷新列表</el-button>
      </div>
    </Layout-item>
    <layout-main :scroll="false">
      <el-table v-if="activeTab === 'init'" ref="tableRef" height="100%" :data="list" :span-method="arraySpanMethod"
        @selection-change="handleSelectionChange">
        <el-table-column prop="selection" type="selection" :selectable="selectable" />
        <el-table-column prop="doctorName" label="医生" :width="140">
          <template #default="{ row }">
            <div class="flex items-center">
              <el-popover v-if="lastFailReason[row.rxId]" :width="400" title="" :content="lastFailReason[row.rxId]"
                placement="top-start">
                <div>
                  <div class="text-red-500 text-16px font-semibold">审核操作失败</div>
                  <div class="text-red-500 text-14px leading-normal mt-5px">{{ lastFailReason[row.rxId] }}</div>
                </div>
                <template #reference>
                  <el-icon class="text-red-500 mr-5px text-18px transform -translate-y-1px cursor-pointer">
                    <Warning />
                  </el-icon>
                </template>
              </el-popover>
              <div>{{ row.doctorName }}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="name" label="患者" :width="140">
          <template #default="{ row }">
            <el-text type="primary" class="cursor-pointer" @click="showInfo(row)">{{ row.order.name }}</el-text>
          </template>
        </el-table-column>
        <el-table-column label="药品" prop="drugName" :width="260">
          <template #default="{ row }">
            <el-popover v-if="row.prescriptionType === 'medicalWinePurchase'" placement="top" :width="320"
              trigger="hover">
              <template #reference>
                <div class="flex">
                  <el-tag type="danger">中药饮片</el-tag>
                  <div class="ml-1">{{ row.drugName }}</div>
                </div>
              </template>
              <div class="leading-6 text-14px text-dark">
                <div>【中药饮片】{{ row.drugName }}</div>
                <div>【成分】{{ row.details || '' }}</div>
                <!-- <div>【功效】{{ row.efficacy || '' }}</div> -->
              </div>
            </el-popover>
            <div v-else>
              <div>{{ row.drugName }} {{ row.specification || "" }}</div>
              <el-tooltip v-if="row.usage_restriction_desc" effect="dark" :content="row.usage_restriction_desc"
                placement="top">
                <div class="text-red-500 text-12px truncate max-w-220px">*{{ row.usage_restriction_desc }}</div>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="发药数量" prop="quantity" :width="140">
          <template #default="{ row }">{{ row.quantity }} {{ row.unit }}</template>
        </el-table-column>
        <el-table-column label="单次剂量" prop="dosage" :width="140">
          <template #default="{ row }">
            <span v-if="row.dosage > 0">{{ row.dosage }} {{ row.dosage_unit }}</span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="给药方式" prop="usageName" :width="140">
          <template #default="{ row }">
            {{ row.usageName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="频率" prop="frequencyName" :width="140">
          <template #default="{ row }">
            {{ row.frequencyName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="天数（天）" prop="days" :width="140">
          <template #default="{ row }">
            {{ row.days || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="截止时间" prop="restTime" :width="180">
          <template #default="{ row }">
            <span v-if="row.order && row.order.orderStatus === 'completed'" class="text-red-500">
              {{ row.order.expireTime ? dayjs(row.order.expireTime).format("YYYY-MM-DD HH:mm") : "" }}
            </span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="医嘱提交时间" prop="submitTime" :width="180">
          <template #default="{ row }">
            {{ row.createTime ? dayjs(row.createTime).format("YYYY-MM-DD HH:mm") : "" }}
          </template>
        </el-table-column>
        <el-table-column label="科室" prop="deptName" :width="180" />
        <el-table-column label="问诊类型" prop="type" :width="120">
          <template #default="{ row }">
            {{ row.order && row.order.consultType ? ConsultType[row.order.consultType] : '在线复诊' }}
          </template>
        </el-table-column>
        <el-table-column label="处方类型" prop="drugType" :width="120">
          <template #default="{ row }">
            {{ row.prescriptionType === 'medicalWinePurchase' ? '中药处方' : '西药处方' }}
          </template>
        </el-table-column>
        <el-table-column label="" :min-width="0" />
      </el-table>
      <el-table v-else height="100%" :data="list" :span-method="arraySpanMethod">
        <el-table-column prop="status" label="审核状态" :width="120">
          <template #default="{ row }">
            <div v-if="row.status === 'PASS' && row.uploadStatus && row.uploadStatus !== 'uploaded'"
              class="text-red-500 mt-5px">上传his失败</div>
            <div v-else-if="row.status === 'PASS'" class="mx-auto inline-block bg-green-500 text-white rounded-md px-2">
              通过
            </div>
            <el-tooltip v-else-if="row.status === 'UNPASS'" effect="light" :content="row.reasonStr"
              placement="right-start" :disabled="!row.reasonStr" popper-class="max-w-50vw">
              <div class="mx-auto inline-block bg-red-500 text-white rounded-md px-2">未通过</div>
            </el-tooltip>
            <div v-else-if="statusMap[row.status]" class="mx-auto inline-block bg-gray-300 text-white rounded-md px-2">
              {{ statusMap[row.status] }}
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="doctorName" label="医生" :width="140" />
        <el-table-column prop="name" label="患者" :width="140">
          <template #default="{ row }">
            <el-text type="primary" class="cursor-pointer" @click="showInfo(row)">{{ row.order.name }}</el-text>
          </template>
        </el-table-column>
        <el-table-column label="药品" prop="drugName" :width="260">
          <template #default="{ row }">
            <div>{{ row.drugName }} {{ row.specification || "" }}</div>
            <el-tooltip v-if="row.usage_restriction_desc" effect="dark" :content="row.usage_restriction_desc"
              placement="top">
              <div class="text-red-500 text-12px truncate max-w-220px">*{{ row.usage_restriction_desc }}</div>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column label="发药数量" prop="quantity" :width="140">
          <template #default="{ row }">{{ row.quantity }} {{ row.unit }}</template>
        </el-table-column>
        <el-table-column label="单次剂量" prop="dosage" :width="140">
          <template #default="{ row }">
            <span v-if="row.dosage">{{ row.dosage }} {{ row.dosage_unit }}</span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="给药方式" prop="usageName" :width="140">
          <template #default="{ row }">
            {{ row.usageName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="频率" prop="frequencyName" :width="140">
          <template #default="{ row }">
            {{ row.frequencyName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="天数（天）" prop="days" :width="140">
          <template #default="{ row }">
            {{ row.days || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="医嘱提交时间" prop="submitTime" :width="180">
          <template #default="{ row }">
            {{ row.createTime ? dayjs(row.createTime).format("YYYY-MM-DD HH:mm") : "" }}
          </template>
        </el-table-column>
        <el-table-column label="审方时间" prop="auditTime" :width="180">
          <template #default="{ row }">
            {{ row.auditTime ? dayjs(row.auditTime).format("YYYY-MM-DD HH:mm") : "" }}
          </template>
        </el-table-column>
        <el-table-column label="审方药师" prop="pharmacist" :width="180" />
        <el-table-column label="" :min-width="0" />
        <el-table-column v-if="showAction" fixed="right" label="操作" :width="100">
          <template #default="{ row }">
            <el-text
              v-if="row.status === 'PASS' && row.uploadStatus !== 'uploaded' && row.prescriptionType === 'storeMedicinePurchase'"
              plain type="primary" class="cursor-pointer" @click="reUpload(row)">重新上传</el-text>
          </template>
        </el-table-column>
      </el-table>
    </layout-main>
    <layout-item>
      <pagination :totalRow="total" :pageSize="pageSize" :currentPage="page" @handle-size-change="changeSize"
        @handle-current-change="changePage" />
    </layout-item>
  </my-layout>
  <rx-drawer :info="info" :width="width" :memberInfo="memberInfo" :visible="visible" @close="visible = false"
    @change="search()" />
  <reject-modal :memberInfo="memberInfo" :ids="selections" :visible="rejectVisible" :width="width" @close="close"
    @change="search()" />
  <reupload-drawer :memberInfo="memberInfo" :visible="reuploadVisible" @close="reuploadVisible = false"
    @change="$event => reUploadCount = $event" />
</template>
<script setup>
import { computed, onMounted, ref, watch, onUnmounted } from "vue";
import { storeToRefs } from "pinia";
import { useSessionStorage } from "@vueuse/core";
import { ElMessage, ElMessageBox, ElLoading, ElNotification } from "element-plus";
import dayjs from "dayjs";
import useModal from "@/hooks/useModal";
import useElPagination from "@/hooks/useElPagination";
import { getAuditDiagnosisList, getAuditedDiagnosisList, auditDiagnosis, getLatestSubmitTime, getAllDoctorNos, reUploadDiagnosticRecord, setPharmacistOnlineStatus, getPharmacistOnlineStatus, getDrugs } from "@/api/hlw.js";
import { memberStore } from "@/store/member";

import { Select, CloseBold } from "@element-plus/icons-vue";
import { CheckBoxFilter, InputFilter, expandFilterBox } from "@/components/filter-bar";
import MyLayout, { LayoutMain, LayoutItem } from "@/components/layout";
import pagination from "@/components/pagination/pagination.vue";
import rxDrawer from "./rx-drawer.vue";
import rejectModal from "./reject-modal.vue";
import reuploadDrawer from "./reupload-drawer.vue";

const notMergeColumns = ["drugName", "quantity", "dosage", "usageName", "frequencyName", "days"];
const { list, page, pageSize, changePage, changeSize } = useElPagination(getList);
const { memberInfo } = storeToRefs(memberStore());

const statusMap = {
  EXPIRED: '已取消',
  PASS_INVALID: '已取消',
  UNPASS_INVALID: '已取消',
  INVALID: '已取消',
}
const ConsultType = {
  onlineMedicinePurchase: '在线配药',
  onlineConsult: '在线复诊',
  wineConsult: '在线复诊'
}

const total = ref(0);
const activeTab = ref("init");
const name = ref("");
const mobile = ref("");
const doctors = ref([]);
const doctorNos = ref([]);
const selections = ref([]);
const visible = ref(false);
const tableRef = ref();
const loading = ref(false);
const { close, show, visible: rejectVisible, width } = useModal(800);
const info = ref({});
const latestTime = ref(0); // 通过列表接口查询到 最新提交时间
const refreshSubmitTime = ref(0); // 刷新接口获取的最新提交时间
const timer = ref(null);
const showAction = computed(() => list.value.some(i => i.status == 'PASS' && i.uploadStatus !== 'uploaded'))
const isOnline = useSessionStorage("isOnline", false);
const lastFailReason = ref({});
const reUploadCount = ref(0);
const reuploadVisible = ref(false);

function clear() {
  name.value = "";
  mobile.value = "";
  doctorNos.value = [];
  search();
}

function search() {
  page.value = 1;
  getList();
}

function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  if (notMergeColumns.includes(column.property)) return [1, 1];
  return [row.rowSpan, 1];
}

function handleSelectionChange(val) {
  const ids = val.map((item) => item.rxId);
  selections.value = Array.from(new Set(ids));
}

function showInfo(row) {
  info.value = row;
  visible.value = true;
}

async function getList() {
  loading.value = true;
  const api = activeTab.value === "init" ? getAuditDiagnosisList : getAuditedDiagnosisList;
  const res = await api({
    page: page.value,
    pageSize: pageSize.value,
    name: name.value,
    mobile: mobile.value,
    doctorCodes: doctorNos.value,
    pharmacistNo: memberInfo.value.workNo
  });
  const arr = res && res.data && Array.isArray(res.data.list) ? res.data.list : [];
  arr.forEach(i => {
    if (i.prescriptionType === 'medicalWinePurchase') {
      i.drugs = Array.isArray(i.wines) ? i.wines.map(i => ({
        drugName: i.name,
        quantity: i.quantity,
        details: i.details,
        efficacy: i.efficacy,
        unit: i.unit,
      })) : [];
    }
  })
  // 补齐缺失的 usage_restriction_desc
  await enrichUsageRestrictionDesc(arr);
  list.value = getTableData(arr);
  total.value = res && res.data && res.data.total >= 0 ? res.data.total : 0;
  tableRef.value && tableRef.value.clearSelection();
  loading.value = false;
  if (res.data && res.data.latestTime) {
    latestTime.value = res.data.latestTime;
  }
}

async function audit(status) {
  if (selections.value.length) {
    lastFailReason.value = {}
    await ElMessageBox.confirm(`确定${status === "PASS" ? "审核通过" : "审核不通过"}吗？`, "提示", { type: "warning" });
    loading.value = true;
    const { success, message, data } = await auditDiagnosis({
      ids: selections.value,
      pharmacistCACUserId: sessionStorage.getItem("caUserId"),
      status,
      pharmacistNo: memberInfo.value.workNo,
      pharmacist: memberInfo.value.anotherName,
    });
    loading.value = false;
    const failList = data && Array.isArray(data.failList) ? data.failList : [];
    failList.forEach(item => {
      lastFailReason.value[item.id] = item.message;
    });
    if (failList.length) {
      ElNotification({
        title: '存在操作失败的处方',
        message: `本次操作存在${failList.length}条操作失败的处方，请点击表格中的红色叹号查看原因`,
        type: 'error',
      })
    }
    if (success) {
      ElMessage.success(message);
    } else {
      ElMessage.error(message);
    }
    search();
  } else {
    ElMessage.info("请选择数据");
  }
}

function rejectRx() {
  if (selections.value.length) {
    lastFailReason.value = {}
    show();
  } else {
    ElMessage.info("请选择数据");
  }
}

async function enrichUsageRestrictionDesc(diagnosisList) {
  const allDrugs = diagnosisList.reduce((acc, cur) => {
    if (Array.isArray(cur.drugs)) {
      acc.push(...cur.drugs);
    }
    return acc;
  }, []);

  const missingIds = allDrugs
    .filter(d => !d.usage_restriction_desc && d.insurance_code)
    .map(d => d.insurance_code);
  const uniqueMissingIds = Array.from(new Set(missingIds));

  if (uniqueMissingIds.length) {
    try {
      const batchSize = 50; // 每次查询的 insuranceCodes 数量上限，防止请求过大
      const allResults = [];

      for (let i = 0; i < uniqueMissingIds.length; i += batchSize) {
        const batch = uniqueMissingIds.slice(i, i + batchSize);
        // 先请求第一页，然后根据返回的 pages 循环请求所有页
        let page = 1;
        let totalPages = 1;
        while (page <= totalPages) {
          const res = await getDrugs({ insuranceCodes: batch, page, pageSize: batch.length });
          const arr = res && res.data && Array.isArray(res.data.data) ? res.data.data : [];
          allResults.push(...arr);

          if (res && res.data && typeof res.data.pages === 'number') {
            totalPages = res.data.pages;
          } else {
            // 如果没有 pages 字段，且本页数据量小于请求量，则结束；否则尝试下页直到命中空页
            if (arr.length < batch.length) {
              totalPages = page;
            } else {
              // 不确定总页数时，继续尝试直到返回空页或少于 pageSize
              totalPages = page + 1;
            }
          }
          page++;
        }
      }

      const map = allResults.reduce((m, cur) => {
        if (cur && cur.insurance_code) {
          m[cur.insurance_code] = cur;
        }
        return m;
      }, {});

      allDrugs.forEach(d => {
        if (!d.usage_restriction_desc && d.insurance_code && map[d.insurance_code] && map[d.insurance_code].usage_restriction_desc) {
          d.usage_restriction_desc = map[d.insurance_code].usage_restriction_desc;
        }
      });
    } catch (e) {
      // 忽略错误，保持已有数据
      console.warn('补齐 usage_restriction_desc 失败:', e);
    }
  }
}

function getTableData(list) {
  console.log(list)
  const res = list.reduce((acc, cur) => {
    const { drugs, ...rest } = cur;
    const rxId = rest._id;
    if (rest.status === "UNPASS") {
      rest.reasonStr = Array.isArray(rest.reasons) ? rest.reasons.join("，") : "";
    }
    if (Array.isArray(drugs)) {
      drugs.forEach((item, idx) => {
        const row = { ...rest, ...item, usage_restriction_desc: item.usage_restriction_desc || '', drugs, rxId };
        if (idx === 0) {
          row.rowSpan = drugs.length;
          row.selectable = true;
        } else {
          row.rowSpan = 0;
          row.selectable = false;
        }
        acc.push(row);
      });
    }
    return acc;
  }, []);
  console.log(res)

  return res;
}

function setRefresh() {
  timer.value = setTimeout(async () => {
    getSubmitTime();
    setRefresh();
  }, 1000 * 90);
}

function selectable(row, index) {
  return typeof row.selectable === "boolean" ? row.selectable : false;
}

async function getSubmitTime() {
  if (memberInfo.value.workNo) {
    const { data } = await getLatestSubmitTime({ pharmacistNo: memberInfo.value.workNo });
    refreshSubmitTime.value = data && typeof data.data === "number" ? data.data : 0;
    reUploadCount.value = data && typeof data.reUploadCount === 'number' ? data.reUploadCount : 0;
  }
}


async function getDoctors() {
  const { data } = await getAllDoctorNos();
  doctors.value =
    data && data.data && Array.isArray(data.data)
      ? data.data.map((i) => ({
        label: i.doctorName,
        value: i.doctorNo,
      }))
      : [];
}

async function getPharmacistStatus() {
  const { data } = await getPharmacistOnlineStatus({ doctorNo: memberInfo.value.workNo });
  isOnline.value = data && ['online', 'offline'].includes(data.data) ? data.data === 'online' : false;
}

let loadingInstance = ref(null);
async function reUpload(row) {
  loadingInstance.value = ElLoading.service({})
  const { success } = await reUploadDiagnosticRecord(row._id);
  loadingInstance.value.close();
  loadingInstance.value = null;
  if (success) {
    ElMessage.success("重新上传成功");
  } else {
    ElMessage.error("重新上传失败");
  }
  search();
}

async function toggleOnline(val) {
  const res = await setPharmacistOnlineStatus({ onlineStatus: val ? 'online' : 'offline', doctorNo: memberInfo.value.workNo });
  if (res.success) {
    ElMessage[val ? 'success' : 'info'](val ? '已上线' : '已下线');
  } else {
    isOnline.value = !val;
    ElMessage.error(res.message);
  }
}

onMounted(() => {
  if (memberInfo.value.workNo) {
    getPharmacistStatus()
  }
  getDoctors();
});

onUnmounted(() => {
  timer.value && clearTimeout(timer.value);
  loadingInstance.value && loadingInstance.value.close();
});

watch(
  activeTab,
  (n) => {
    search();
    if (n === "init") {
      setRefresh();
    } else {
      clearTimeout(timer.value);
      timer.value = null;
    }
  },
  { immediate: true }
);
</script>