<template>
  <el-drawer :model-value="visible" title="下诊断" size="80%" style="--el-drawer-padding-primary: 0" @close="close()">
    <my-layout v-loading="getting" class="bg-[#f2f3f4]">
      <layout-main ref="mainRef">
        <div class="bg-white">
          <div class="px-15px py-12px bg-[#ecf4ff] bg-opacity-30">
            <div class="pb-10px">
              <span class="text-16px font-semibold">{{ consultInfo.name }}</span>
              <span class="text-14px ml-5px">{{ consultInfo.sex }} {{ consultInfo.age ? consultInfo.age + '岁' : ''
              }}</span>
              <img v-if="consultInfo.signature" :src="consultInfo.signature" class="w-80px h-40px inline-block"
                alt="客户签名" @click="previewImage(consultInfo.signature)">
            </div>
            <el-form class="mt-5px" label-suffix="：">
              <el-row>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="身份证号">{{ consultInfo.idCard }} </el-form-item>
                </el-col>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="卡号">{{ consultInfo.blhno }} </el-form-item>
                </el-col>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="手机号">{{ consultInfo.mobile }} </el-form-item>
                </el-col>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="挂号科室">{{ consultInfo.deptName }} </el-form-item>
                </el-col>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="就诊日期">
                    {{ consultInfo.createTime ? dayjs(consultInfo.createTime).format('YYYY-MM-DD HH:mm') : '' }}
                  </el-form-item>
                </el-col>
                <el-col :lg="8" :md="12" :xs="24">
                  <el-form-item class="mb-0" label="医生">{{ consultInfo.doctorName }} </el-form-item>
                </el-col>
              </el-row>
            </el-form>
          </div>
        </div>
        <div class="flex items-center px-15px py-12px mt-15px bg-white border-b border-gray-200">
          <div class="flex items-center">
            <div class="text-15px font-semibold">开医嘱</div>
            <div v-if="prescriptionStartEffective" class="ml-8px flex items-center">
              <span class="text-14px font-medium prescription-label">开方时长：</span>
              <span class="text-14px font-medium prescription-value">{{ formattedPrescriptionTime }}</span>
            </div>
          </div>

          <div v-if="dbRecord.status === 'INIT'"
            class="ml-10px px-12px text-12px py-6px bg-blue-200 text-blue-500 bg-opacity-30 rounded">处方审核中</div>
          <div v-if="dbRecord.status === 'EXPIRED'"
            class="ml-10px px-12px text-12px py-6px bg-gray-200 text-gray-500 bg-opacity-30 rounded">订单已过期</div>
          <div v-else-if="dbRecord.status === 'PASS'"
            class="ml-10px px-12px text-12px py-6px bg-green-200 text-green-500 bg-opacity-30 rounded">审核通过</div>
          <template v-else-if="dbRecord.status === 'UNPASS'">
            <div class="ml-10px px-12px text-12px py-6px bg-red-200 text-red-500 bg-opacity-30 rounded">
              未通过
            </div>
            <el-tooltip effect="light" placement="bottom" :content="reasonStr" :disabled="!reasonStr"
              popper-class="max-w-50vw">
              <div v-if="reasonStr" class="w-0 text-14px flex-grow text-red-500 ml-5px truncate">原因：{{ reasonStr }}
              </div>
            </el-tooltip>
          </template>
        </div>
        <div class="px-15px py-12px bg-white">
          <div active-title-bar>填写门诊病历</div>
          <el-form class="mt-10px" label-position="top">
            <el-form-item class="is-required mb-5px" label="主诉（就诊意愿）">
              <el-input v-model="form.complaint" :readonly="readonly" type="textarea" resize="none"
                :autosize="{ minRows: 2, maxRows: 4 }" :maxlength="500" placeholder="请输入主诉（就诊意愿）" show-word-limit />
            </el-form-item>
            <el-form-item label="现病史" class="mb-5px">
              <el-input v-model="form.presentIllness" :readonly="readonly" type="textarea" resize="none"
                :autosize="{ minRows: 2, maxRows: 4 }" :maxlength="500" placeholder="请输入现病史" show-word-limit />
            </el-form-item>
            <el-form-item label="处置" class="mb-5px">
              <el-input v-model="form.dispose" type="textarea" resize="none" :readonly="readonly"
                :autosize="{ minRows: 2, maxRows: 4 }" :maxlength="500" placeholder="请输入处置" show-word-limit />
            </el-form-item>
          </el-form>
          <div active-title-bar class="mt-10px">
            <span>诊断</span>
            <el-button v-if="!readonly" class="ml-10px" :icon="Plus" size="small" type="primary" plain
              @click="addDiagnosis">添加</el-button>
          </div>
          <el-form class="mt-10px" :class="readonly ? 'pointer-events-none' : ''">
            <el-form-item v-for="(item, idx) in diagnosisList" class="border-dashed border-b border-gray-200">
              <template #label>
                <span class="mr-5px">诊断{{ diagnosisList.length - idx }}</span>
              </template>
              <div class="flex w-0 flex-grow items-center pb-10px">
                <el-row class="w-full" :gutter="10">
                  <el-col :lg="12" :md="12">
                    <el-select v-model="item.code" filterable remote reserve-keyword class="w-full"
                      :loading="item.loading" placeholder="请搜索诊断" :remote-method="str => searchDiagnosis(str, idx)"
                      @change="changeDiagnosis($event, idx)">
                      <el-option-group v-if="item.name" label="当前诊断">
                        <el-option :label="item.name" :value="item.code">
                          <div class="flex justify-between">
                            <div>{{ item.name }}</div>
                            <div>{{ item.code }}</div>
                          </div>
                        </el-option>
                      </el-option-group>
                      <el-option-group label="搜索结果">
                        <el-option v-for="opt in item.options" :key="opt.code" :label="opt.name" :value="opt.code">
                          <div class="flex justify-between">
                            <div>{{ opt.name }}</div>
                            <div>{{ opt.code }}</div>
                          </div>
                        </el-option>
                      </el-option-group>
                    </el-select>
                  </el-col>
                  <el-col :lg="12" :md="12">
                    <el-input v-model="item.desc" :readonly="readonly" maxlength="100" class="w-full"
                      placeholder="补充说明" />
                  </el-col>
                </el-row>
                <el-button v-if="!readonly" text class="cursor-pointer" type="danger" :icon="Delete"
                  @click="removeDia(idx)" />
              </div>
            </el-form-item>
          </el-form>
          <template v-if="order && order.consultType === 'wineConsult'">
            <wine-table ref="wineTable" :wines="wines" @change="changeWine($event)" />
          </template>
          <template v-else>
            <div active-title-bar>西医处方</div>
            <div class="flex items-center mt-10px">
              <div class="flex-grow w-0">
                <el-tabs v-model="currentTab" type="card" class="demo-tabs" @tab-remove="removeTab">
                  <el-tab-pane v-for="(tab, idx) in tabs" :key="tab.name" :label="`处方${idx + 1}`" :name="tab.name" />
                </el-tabs>
              </div>
            </div>
            <div class="flex items-center pb-10px">
              <el-button plain type="primary" class="opacity-0">保存模板</el-button>
              <div class="flex-grow"></div>
              <template v-if="!readonly">
                <el-button type="primary" @click="addDrug()">添加药品</el-button>
                <el-button plain @click="clearDrug()">清空</el-button>
              </template>
            </div>
            <el-table height="50vh" :data="drugs" @keyup.enter="onEnter">
              <el-table-column label="序号" prop="index" :width="60">
                <template #default="{ $index }">{{ $index + 1 }}</template>
              </el-table-column>
              <el-table-column align="center" label="强制自费" prop="index" :width="80">
                <template #default="{ row, $index }">
                  <el-checkbox :class="readonly ? 'pointer-events-none' : ''" :model-value="row.forceSelfPay === 'Y'"
                    @update:model-value="changeForcePay($index)" />
                </template>
              </el-table-column>
              <el-table-column label="药品" prop="drugName" :min-width="220">
                <template #default="{ row: item, $index }">
                  <el-select v-model="item.insurance_code" filterable remote reserve-keyword class="w-full"
                    :class="readonly ? 'pointer-events-none' : ''" :loading="item.loading" placeholder="请搜索药品"
                    :remote-method="str => searchDrug(str, $index)" @change="changeDrug($event, $index)">
                    <el-option-group v-if="item.drugName" label="当前药品">
                      <el-option :label="item.drugName" :value="item.insurance_code" />
                    </el-option-group>
                    <el-option-group label="搜索结果">
                      <el-option :style="optionWidth" v-for="opt in item.options" :key="opt.insurance_code"
                        :label="opt.name" :value="opt.insurance_code">
                        <div class="flex items-center justify-between">
                          <div class="w-0 flex-grow truncate"
                            :title="(opt.name || '') + (opt.specification || '') + (opt.manufacturer || '')"> {{
                              opt.name
                            }}
                            {{ opt.specification }} {{ opt.manufacturer }} </div>
                        </div>
                      </el-option>
                    </el-option-group>
                  </el-select>
                  <el-tooltip v-if="item.specification" effect="light" placement="bottom-start"
                    popper-class="max-w-480px" :disabled="!item.usage_restriction_desc">
                    <template #content>
                      <span class="text-red-500">*{{ item.usage_restriction_desc }}</span>
                    </template>
                    <div class="drug-spec-line text-14px text-gray-500">
                      规格：{{ item.specification }}
                      <span v-if="item.usage_restriction_desc" class="drug-spec-limit text-red-500">
                        *{{ item.usage_restriction_desc }}
                      </span>
                    </div>
                  </el-tooltip>
                </template>
              </el-table-column>
              <el-table-column label="单次剂量" prop="dosage" :min-width="100">
                <template #default="{ row, $index }">
                  <el-input v-model="row.dosage" :readonly="readonly" @input="setCalculateTimer($index)" />
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="剂量单位" prop="dosage_unit" :min-width="80">
                <template #default="{ row, $index }">
                  <el-select v-model="row.dosage_unit" filterable @change="changeDosageUnit($event, $index)">
                    <el-option v-for="i in dosageUnitList" :key="i.code" :label="i.name" :value="i.code"></el-option>
                  </el-select>
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="频次" prop="frequencyCode" :min-width="140">
                <template #default="{ row, $index }">
                  <el-select v-model="row.frequencyCode" filterable class="w-full" placeholder="请选择频次"
                    :class="readonly ? 'pointer-events-none' : ''" @change="changeFrequency($event, $index)">
                    <el-option v-for="item in frequencyList" :key="item.code" :label="item.name" :value="item.code" />
                  </el-select>
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="发药数量" prop="quantity" :min-width="80">
                <template #default="{ row }">
                  <el-input v-model="row.quantity" placeholder="请输入发药数量" :readonly="readonly" />
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="发药单位" prop="unit" :min-width="100">
                <template #default="{ row }">
                  <el-select v-model="row.unit">
                    <el-option v-for="i in unitList" :key="i.code" :label="i.name" :value="i.code"></el-option>
                  </el-select>
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="用药天数" prop="days" :min-width="80">
                <template #default="{ row, $index }">
                  <el-input v-model="row.days" placeholder="请输入用药天数" :readonly="readonly"
                    @input="setCalculateTimer($index)" />
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="给药方式" prop="usageCode" :min-width="140">
                <template #default="{ row, $index }">
                  <el-select v-model="row.usageCode" filterable class="w-full" placeholder="请选择给药方式"
                    :class="readonly ? 'pointer-events-none' : ''" @change="changeUsage($event, $index)">
                    <el-option v-for="item in usageList" :key="item.code" :label="item.name" :value="item.code" />
                  </el-select>
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
              <el-table-column label="" prop="blank" :min-width="1" />
              <el-table-column fixed="right" label="操作" prop="action" :width="100">
                <template #default="{ row, $index }">
                  <el-text class="cursor-pointer mr-10px" type="primary" @click="copyDrugInfo($index)">复制</el-text>
                  <el-text v-if="!readonly" class="cursor-pointer" type="danger" @click="remove($index)">删除</el-text>
                  <div v-if="row.specification" class="h-20px"></div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </div>
      </layout-main>
      <layout-item v-if="!readonly">
        <div common-shadow--r class="py-12px bg-white text-center relative z-1">
          <el-button :disabled="disableFirstSubmit" type="primary" :loading="loading" @click="verify()">
            {{ dbRecord.status === 'UNPASS' ? '重新提交医嘱' : '提交医嘱' }}
          </el-button>
          <el-button plain type="primary" @click="showPreview">预览医嘱</el-button>
          <el-button plain type="info" @click="saveDraft()">保存草稿</el-button>
          <el-button v-if="hasDraft" plain type="danger" @click="clearDraft(true)">清空草稿</el-button>
          <el-button plain type="danger" @click="clearAll()">清空</el-button>
        </div>
      </layout-item>
    </my-layout>
  </el-drawer>
  <el-image-viewer v-if="showViewer" :url-list="images" @close="showViewer = false" />
  <preview-modal :visible="previewVisible" :order="consultInfo" :form="form" :diagnosisList="diagnosisList"
    :drugs="drugs" @close="previewVisible = false" />
  <unsuit-drug-model :drugs="inappropriateDrugs" :visible="unsuitableDrugVisible"
    @close="unsuitableDrugVisible = false" />
  <repeat-drug-model :drugs="repeatDrugs" :visible="repeatDrugVisible" @close="repeatDrugVisible = false"
    @confirm="submit()" />
  <advice-modal :advices="adviceList" :visible="adviceModalVisible" @close="cancelAdviceModal"
    @confirm="submit(true)" />
</template>
<script setup>
import { computed, nextTick, ref, watch, onMounted, onUnmounted } from "vue";
import { storeToRefs } from "pinia";
import { useWindowSize } from '@vueuse/core'
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
import dayjs from 'dayjs';
import { getHlwDiagnosisList, getDrugs, getOrderDiagnosis, addConsultDiagnosis, getOnlineDrugList, getHisDrugInfo, getConsultOrder, getHlwOrderConfig, getYbReviewResult } from '@/api/hlw.js'
import useModal from '@/hooks/useModal';
import medicineInfoStore from "@/store/medicine-info";
import { getRandomStr, useCopy } from "@/utils";
import useWine from './wine-hook.js'

import MyLayout, { LayoutMain, LayoutItem } from "@/components/layout";
import { Delete, Plus } from "@element-plus/icons-vue";
import previewModal from './preview-modal.vue'
import UnsuitDrugModel from './unsuit-drug-model.vue'
import RepeatDrugModel from './repeat-drug-model.vue'
import AdviceModal from './advice-modal.vue'
import WineTable from './wine-table.vue'

// 不参与计算 推荐数量的单次剂量单位
const excludeCalculateUnit = ['滴'];

const props = defineProps({
  canEdit: {
    type: Boolean,
    default: false
  },
  order: {
    type: Object,
    default: () => ({})
  },
  visible: {
    type: Boolean,
    default: false,
  },
  prescriptionStartTime: {
    type: Number,
    default: null
  },
  prescriptionEndTime: {
    type: Number,
    default: null
  }
});

const initalForm = {
  complaint: '', // 主诉
  presentIllness: '', // 现病史
  dispose: '' // 处置
}
const emit = defineEmits(["close", "onDiagnosisSubmited"]);
const { attachMedicineConfig } = medicineInfoStore();
const { onlineMedicine, storeMedicine } = storeToRefs(medicineInfoStore())
const medicineUseInfo = computed(() => props.order.consultType === 'onlineMedicinePurchase' ? onlineMedicine.value : storeMedicine.value)
const usageList = computed(() => medicineUseInfo.value.usageList)
const frequencyList = computed(() => medicineUseInfo.value.frequencyList)
const dosageUnitList = computed(() => medicineUseInfo.value.dosageUnitList)
const unitList = computed(() => medicineUseInfo.value.unitList)
const getDrugsApi = computed(() => props.order.consultType === 'onlineMedicinePurchase' ? getOnlineDrugList : getDrugs);

const mainRef = ref(null);
const currentTab = ref('drug-1');
const tabs = ref([{ name: 'drug-1', drugs: [] }])
const form = ref({ ...initalForm });
const diagnosisList = ref([{ name: '', code: '', options: [], key: getRandomStr(), loading: false, desc: '' }]);
const tabIndex = computed(() => tabs.value.findIndex(i => i.name === currentTab.value))
const drugs = computed(() => {
  const tab = tabs.value[tabIndex.value];
  return tab ? tab.drugs : null;
})
const loading = ref(false);
const getting = ref(false);
const dbRecord = ref({});
const readonly = computed(() => !props.canEdit || dbRecord.value && ['INIT', 'PASS', 'EXPIRED'].includes(dbRecord.value.status))
const reasonStr = computed(() => dbRecord.value && Array.isArray(dbRecord.value.reasons) ? dbRecord.value.reasons.join('，') : '')
const { width } = useWindowSize()
const optionWidth = computed(() => ({ width: `${Math.floor(width.value * .65)}px` }))
const { close: cancelPreview, show: showPreview, visible: previewVisible, width: previewWidth } = useModal(800);
const { close: cancelUnsuitDrug, show: showUnsuitDrug, visible: unsuitableDrugVisible, width: unsuitableDrugWidth } = useModal(640);
const { close: cancelRepeatDrug, show: showRepeatDrug, visible: repeatDrugVisible, width: repeatDrugWidth } = useModal(640);
const { close: cancelAdviceModal, show: showAdviceModal, visible: adviceModalVisible, width: adviceModalWidth } = useModal(640);

const adviceList = ref([]);

const previewParams = ref({})
const hasDraft = ref(false);
const showViewer = ref(false)
const images = ref([]);
const consultInfo = ref({});
const { checkWines, changeWine, wines, initWines } = useWine();
const firstSubmitRxIntervel = ref(0);
let notify = null

const inappropriateDrugs = computed(() => {
  const sex = props.order?.sex;
  const opposingGender = sex === '男' ? 'female' : (sex === '女' ? 'male' : '');
  const gender = sex === '男' ? '女' : '男';
  const isAdult = Number(props.order?.age) > 16
  // 性别不适应或儿童用药不适应
  return drugs.value.map(i => {
    const data = { ...i };
    const genderError = opposingGender && i.suitableGender === opposingGender;
    const childError = isAdult && i.suitableChild;
    if (genderError && childError) {
      data.errMsg = `该药品仅限${gender}性使用，且为儿童（≤16周岁）用药。`
    } else if (genderError) {
      data.errMsg = `该药品仅限${gender}性使用。`
    } else if (childError) {
      data.errMsg = `该药品仅限儿童（≤16周岁）用药。`
    }
    return data
  }).filter(i => Boolean(i.errMsg))
})

const repeatDrugs = computed(() => {
  // 按 repeatTag 分组药品
  const tagGroups = {};
  drugs.value.forEach(drug => {
    const repeatTags = Array.isArray(drug.repeatTag) ? drug.repeatTag : [];
    repeatTags.forEach(tag => {
      if (!tagGroups[tag]) tagGroups[tag] = [];
      tagGroups[tag].push(drug);
    });
  });

  // 过滤出有重复的组，生成提示文本，并基于 idStr 去重
  const uniqueGroups = new Map();
  Object.values(tagGroups)
    .filter(drugs => drugs.length > 1)
    .forEach(drugs => {
      const idStr = drugs.map(d => d._id).sort().join(',');
      // 如果该组合已存在，跳过（去重）
      if (uniqueGroups.has(idStr)) return;

      const drugNames = drugs.map(d => `【${d.drugName}】`).join('、');
      uniqueGroups.set(idStr, `${drugNames}存在重复用药`);
    });

  return Array.from(uniqueGroups.values());
})

// 开方时长计算（支持 props 回传 + 已有 dbRecord 回显）
const prescriptionStartEffective = computed(() => props.prescriptionStartTime || (dbRecord.value && dbRecord.value.prescriptionStartTime) || null);
const prescriptionEndEffective = computed(() => props.prescriptionEndTime || (dbRecord.value && dbRecord.value.prescriptionEndTime) || null);
const prescriptionElapsed = ref(0);
const disableFirstSubmit = computed(() => prescriptionElapsed.value < firstSubmitRxIntervel.value); // 震元要求 接诊后一定时间内不能提交开方(后台配置)
let prescriptionTimer = null;

const formattedPrescriptionTime = computed(() => {
  const hours = Math.floor(prescriptionElapsed.value / 3600);
  const minutes = Math.floor((prescriptionElapsed.value % 3600) / 60);
  const seconds = prescriptionElapsed.value % 60;
  return `${hours}时${minutes < 10 ? "0" : ""}${minutes}分${seconds < 10 ? "0" : ""}${seconds}秒`;
});

function updatePrescriptionElapsed() {
  const start = prescriptionStartEffective.value;
  if (!start) {
    prescriptionElapsed.value = 0;
    return;
  }
  const end = prescriptionEndEffective.value || Date.now();
  const elapsed = end - start;
  prescriptionElapsed.value = elapsed > 0 ? Math.floor(elapsed / 1000) : 0;
}

function startPrescriptionTimer() {
  if (prescriptionTimer) {
    clearInterval(prescriptionTimer);
  }
  if (prescriptionStartEffective.value && !prescriptionEndEffective.value) {
    prescriptionTimer = setInterval(() => {
      updatePrescriptionElapsed();
    }, 1000);
  }
}

function stopPrescriptionTimer() {
  if (prescriptionTimer) {
    clearInterval(prescriptionTimer);
    prescriptionTimer = null;
  }
}

function close() {
  emit("close");
}

function removeTab(name) {
  if (tabs.value.length === 1) return;
  tabs.value = tabs.value.filter(tab => tab.name !== name);
  if (currentTab.value === name) {
    currentTab.value = tabs.value[0].name || ''
  }
}

function addTab() {
  tabs.value.push({ name: `drug-${Date.now()}`, drugs: [{}] })
}

function addDrug() {
  const tab = tabs.value[tabIndex.value];
  tab.drugs = Array.isArray(tab.drugs) ? tab.drugs : [];
  if (tab.drugs.length < 5) {
    tab.drugs.push({})
  } else {
    ElMessage.info('最多添加5个药品')
  }
}

async function searchDiagnosis(string, idx) {
  const item = diagnosisList.value[idx];
  item.loading = true;
  if (item.timer) {
    clearTimeout(item.timer)
  }
  item.timer = setTimeout(async () => {
    if (string.trim()) {
      const { data } = await getHlwDiagnosisList({ keyword: string, page: 1, pageSize: 30 });
      item.options = data && Array.isArray(data.data) ? data.data : [];
    }
    item.timer = null
    item.loading = false;
  }, 500)
}

function changeDiagnosis(val, idx) {
  const item = diagnosisList.value[idx];
  const d = item.options.find(o => o.code === val);
  item.name = d.name;
  item.code = d.code;
}

function addDiagnosis() {
  diagnosisList.value.unshift({ name: '', code: '', options: [], key: getRandomStr(), loading: false, desc: '' });
}

async function removeDia(idx) {
  const d = diagnosisList.value[idx];
  if (d && d.code) {
    await ElMessageBox.confirm('确定删除该诊断吗？', '提示', { type: 'warning' })
  }
  diagnosisList.value.splice(idx, 1)
}

async function searchDrug(string, idx) {
  const item = tabs.value[tabIndex.value].drugs[idx];
  item.loading = true;
  if (item.timer) {
    clearTimeout(item.timer)
  }
  item.timer = setTimeout(async () => {
    if (string.trim()) {
      const { data } = await getDrugsApi.value({ keyword: string, page: 1, pageSize: 30 });
      item.options = data && Array.isArray(data.data) ? data.data : [];
    }
    item.timer = null
    item.loading = false;
  }, 500)
}

function changeDrug(val, idx) {
  const item = tabs.value[tabIndex.value].drugs[idx];
  const d = item.options.find(o => o.insurance_code === val);
  item._id = d._id;
  item.drugName = d.name;
  item.product_id_str = d.product_id_str;
  item.product_id = d.product_id;
  item.insurance_code = d.insurance_code;
  item.dosage = d.dosage;
  const dosageUnit = dosageUnitList.value.find(i => i.name === d.dosage_unit);
  item.dosage_unit = dosageUnit ? dosageUnit.name : '';
  item.dosage_unit_code = dosageUnit ? dosageUnit.code : '';
  item.quantity = d.quantity || d.recommended_quantity || '';
  item.days = d.days || '';
  const usage = usageList.value.find(i => i.name === d.administration_method);
  item.usageName = usage ? usage.name : '';
  item.usageCode = usage ? usage.code : '';
  const frequency = frequencyList.value.find(item => item.name === d.freq);
  item.frequencyName = frequency ? frequency.name : '';
  item.frequencyCode = frequency ? frequency.code : '';
  item.unit = d.unit || '';
  item.specification = d.specification || '';
  item.package_amount = d.package_amount
  item.recommended_quantity = d.recommended_quantity;
  // 新增：使用限制与用药证明描述，用于前端提示
  item.usage_restriction_desc = d.usage_restriction_desc || '';
  item.medication_proof_desc = d.medication_proof_desc || '';
  item.suitableChild = d.suitableChild;
  item.suitableGender = d.suitableGender;
  item.repeatTag = d.repeatTag;
}

function changeUsage(val, idx) {
  const item = tabs.value[tabIndex.value].drugs[idx];
  const usage = usageList.value.find(i => i.code === val);
  item.usageName = usage ? usage.name : '';
  item.usageCode = usage ? usage.code : '';
}

function changeFrequency(val, idx) {
  const item = tabs.value[tabIndex.value].drugs[idx];
  const frequency = frequencyList.value.find(item => item.code === val);
  item.frequencyName = frequency ? frequency.name : '';
  item.frequencyCode = frequency ? frequency.code : '';
  setCalculateTimer(idx)
}

function changeDosageUnit(val, idx) {
  const item = tabs.value[tabIndex.value].drugs[idx];
  const dosageUnit = dosageUnitList.value.find(item => item.code === val);
  item.dosage_unit_code = dosageUnit ? dosageUnit.code : '';
  item.dosage_unit = dosageUnit ? dosageUnit.name : '';
}

function onEnter(e) {
  if (e.target && e.target.nodeName == 'INPUT') {
    addDrug()
  }
}

async function verify(ignoreRepeat = false) {
  if (form.value.complaint.trim() === '') {
    ElMessage.info('请输入主诉');
    return
  }
  const validDiagnosisList = diagnosisList.value.filter(i => (i.code && i.name));
  if (validDiagnosisList.length === 0) {
    ElMessage.info('请完善诊诊断信息');
    return;
  }
  const drugs = tabs.value[0].drugs.filter(i => (i.insurance_code && i.drugName));
  if (consultInfo.value.consultType === 'wineConsult') {
    const msg = checkWines();
    if (msg) {
      return ElMessage.info(msg);
    }
  } else {
    if (drugs.length === 0) {
      return ElMessage.info('请添加处方药品');
    }
    for (let i of drugs) {
      if (!(i.dosage > 0) || !validateNumber(i.dosage)) {
        ElMessage.info(`${i.drugName}: 单次剂量无效`);
        return;
      }
      if (!dosageUnitList.value.some(item => item.code === i.dosage_unit_code)) {
        ElMessage.info(`${i.drugName}: 剂量单位无效`);
        return;
      }
      if (!i.frequencyCode) {
        ElMessage.info(`${i.drugName}: 频次无效`);
        return;
      }
      if (!(i.quantity > 0 && Number.isInteger(Number(i.quantity)))) {
        ElMessage.info(`${i.drugName}: 发药数量无效`);
        return;
      }
      if (!unitList.value.some(item => item.code === i.unit)) {
        ElMessage.info(`${i.drugName}: 发药单位无效`);
        return;
      }
      if (!(i.days > 0 && Number.isInteger(Number(i.days)))) {
        ElMessage.info(`${i.drugName}: 用药天数无效`);
        return;
      }
      if (!i.usageCode) {
        ElMessage.info(`${i.drugName}: 给药方式无效`);
        return;
      }
    }
    if (inappropriateDrugs.value.length) {
      return showUnsuitDrug()
    }
    if (repeatDrugs.value.length) {
      return showRepeatDrug()
    }
    if (props.order.consultType === 'onlineMedicinePurchase') {
      await checkStock(drugs)
    }
  }
  await ElMessageBox.confirm('确定提交诊断吗？', '提示', { type: 'warning' });
  submit()
}

async function submit(ignoreReview = false) {
  if (loading.value) return;
  loading.value = true;
  const validDiagnosisList = diagnosisList.value.filter(i => (i.code && i.name));
  const drugs = tabs.value[0].drugs.filter(i => (i.insurance_code && i.drugName));
  const params = {
    ...form.value,
    doctorCAUserId: sessionStorage.getItem("caUserId"),
    patientId: consultInfo.value.patientId,
    name: consultInfo.value.name,
    orderId: consultInfo.value.orderId,
    doctorCode: consultInfo.value.doctorCode,
    doctorName: consultInfo.value.doctorName,
    deptName: consultInfo.value.deptName,
    unitCode: consultInfo.value.unitCode,
    drugStoreNo: consultInfo.value.drugStoreNo,
    orderSource: consultInfo.value.orderSource,
    idCard: consultInfo.value.idCard,
    blhno: consultInfo.value.blhno,
    medOrgOrderNo: consultInfo.value.medorg_order_no,
    address: consultInfo.value.address,
    mobile: consultInfo.value.mobile,
    diagnosisList: validDiagnosisList.map(i => ({
      code: i.code,
      name: i.name,
      desc: i.desc || ''
    })),
    drugs: drugs.map(i => ({
      _id: i._id,
      days: Number(i.days),
      dosage: Number(i.dosage),
      dosage_unit: i.dosage_unit,
      dosage_unit_code: i.dosage_unit_code,
      drugName: i.drugName,
      specification: i.specification,
      frequencyCode: i.frequencyCode,
      frequencyName: i.frequencyName,
      insurance_code: i.insurance_code,
      product_id: i.product_id,
      quantity: Number(i.quantity),
      unit: i.unit,
      usageCode: i.usageCode,
      usageName: i.usageName,
      package_amount: i.package_amount,
      recommended_quantity: i.recommended_quantity,
      forceSelfPay: ['Y', 'N'].includes(i.forceSelfPay) ? i.forceSelfPay : 'N',
      limitUsageScope: typeof i.usage_restriction_desc === 'string' && i.usage_restriction_desc.trim() ? 'Y' : 'N'
    })),
    wines: wines.value
  }
  // , 'onlineMedicinePurchase'
  if (!ignoreReview && ['onlineConsult'].includes(props.order.consultType)) {
    const result = await getYbReviewResult(params);
    if (!result || !result.success) {
      ElMessage.error(result.message || '医保审核失败');
      loading.value = false;
      return
    }
    const advices = result.data && Array.isArray(result.data.advices) ? result.data.advices : [];
    if (advices.length) {
      adviceList.value = advices;
      showAdviceModal()
      loading.value = false;
      return
    }
  }
  const { success, data, message } = await addConsultDiagnosis(params);
  loading.value = false
  if (success) {
    ElMessage.success('提交成功')
    clearDraft()
    emit('onDiagnosisSubmited')
    close()
  } else {
    ElMessage.error(message || '提交失败')
  }
}

function remove(idx) {
  tabs.value[0].drugs.splice(idx, 1)
}

function copyDrugInfo(idx) {
  const drug = tabs.value[0].drugs[idx];
  if (drug && drug.drugName) {
    const spec = drug.specification ? `（${drug.specification}）` : '';
    const memo = [drug.usageName, drug.frequencyName, (drug.dosage || '') + (drug.dosage_unit || '')].filter(Boolean).join('，')
    const txt = `
    药品：${drug.drugName}${spec}
    数量：${drug.quantity}${drug.unit}
    用法用量：${memo}
    `
    useCopy(txt, '已复制药品信息')
  }
}

function clearDrug() {
  tabs.value[0].drugs = [];
}

async function init() {
  getting.value = true;
  wines.value = [];
  try {
    await attachMedicineConfig();
    getSubmitInterval()
    const draft = sessionStorage.getItem(`draftDiagnosis-${consultInfo.value.orderId}`);
    hasDraft.value = Boolean(draft);
    if (props.canEdit && draft) {
      const { form: _form, diagnosisList: _diagnosisList, drugs: _drugs, wines: _wines } = JSON.parse(draft);
      form.value = { ..._form };
      diagnosisList.value = _diagnosisList;
      tabs.value[0].drugs = _drugs;
      wines.value = Array.isArray(_wines) ? _wines : [];
      getting.value = false
      return
    }
    await getRecord();
    if (dbRecord.value && dbRecord.value._id) {
      await enrichRecordDrugsInfo();
      initWithRecord()
    } else {
      initWithOrder()
    }
  } catch (e) { }
  getting.value = false;
}

/**
 * 获取已经提交的诊断信息
 */
async function getRecord() {
  const { success, data, message } = await getOrderDiagnosis({ orderId: consultInfo.value.orderId, doctorNo: consultInfo.value.doctorCode });
  if (!success) {
    ElMessage.error(message || '获取诊断信息失败')
    close();
    return Promise.reject('获取记录失败')
  }
  dbRecord.value = data.data || {}
}

async function enrichRecordDrugsInfo() {
  const record = dbRecord.value;
  if (!record || !Array.isArray(record.drugs)) return;

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

  if (uniqueMissingIds.length) {
    try {
      const { data } = await getDrugsApi.value({ insuranceCodes: uniqueMissingIds, page: 1, pageSize: uniqueMissingIds.length });
      const arr = data && Array.isArray(data.data) ? data.data : [];
      const map = arr.reduce((m, cur) => {
        if (cur.insurance_code) {
          m[cur.insurance_code] = cur;
        }
        return m;
      }, {});

      record.drugs.forEach(d => {
        const drugInfo = map[d.insurance_code];
        if (drugInfo) {
          if (!d.usage_restriction_desc && drugInfo.usage_restriction_desc) {
            d.usage_restriction_desc = drugInfo.usage_restriction_desc;
          }
          if (!d.medication_proof_desc && drugInfo.medication_proof_desc) {
            d.medication_proof_desc = drugInfo.medication_proof_desc;
          }
        }
      });
    } catch (e) {
      console.warn('补齐记录药品信息失败:', e);
    }
  }
}

async function initWithRecord() {
  const record = dbRecord.value;
  Object.keys(initalForm).forEach(key => {
    form.value[key] = record[key];
  })
  diagnosisList.value = Array.isArray(record.diagnosisList) ? record.diagnosisList.map(i => ({ ...i, key: getRandomStr(), loading: false })) : [{ key: getRandomStr(), loading: false }]

  const recordDrugs = Array.isArray(record.drugs) ? record.drugs.map(drug => ({
    ...drug,
    usage_restriction_desc: drug.usage_restriction_desc || '',
    medication_proof_desc: drug.medication_proof_desc || '',
    suitableChild: drug.suitableChild,
    suitableGender: drug.suitableGender,
    repeatTag: drug.repeatTag
  })) : [{}];
  await initWines(record.wines.map(i => ({ ...i, id: i._id })));
  tabs.value[0].drugs = recordDrugs;
}

async function initWithOrder() {
  const order = consultInfo.value;
  tabs.value[0].drugs = [];
  Object.keys(initalForm).forEach(key => {
    form.value[key] = initalForm[key];
  })
  diagnosisList.value = [{ key: getRandomStr(), loading: false }];
  const str = order && Array.isArray(order.diseases) ? order.diseases.join('，') : '';
  const pastHistoryStr = order && typeof order.pastHistoryStr === 'string' ? order.pastHistoryStr : '';
  const description = order && typeof order.description === 'string' ? order.description : '';
  const wine = order && order.consultType === 'wineConsult' && order.wines ? order.wines[0] : null;
  if (order.consultType === 'wineConsult') {
    form.value.complaint = `${wine && wine.cate ? `（${wine.cate}）` : ''}${description}`;
  } else {
    form.value.complaint = `${str} ${description}`;
  }
  form.value.presentIllness = pastHistoryStr;
  await initWines(order.wines);
  const orderDrugs = order && Array.isArray(order.drugs) ? order.drugs : [];
  if (orderDrugs.length) {
    const { data } = await getDrugsApi.value({ page: 1, pageSize: orderDrugs.length * 2, ids: orderDrugs.map(i => i._id) })
    const list = data && Array.isArray(data.data) ? data.data : [];
    const errorDrugs = [];
    const _drugs = orderDrugs.reduce((acc, cur) => {
      const drug = list.find(i => i._id === cur._id)
      if (drug && drug.onSale) {
        const row = { options: [drug], loading: false };
        row._id = drug._id;
        row.drugName = drug.name;
        row.product_id_str = drug.product_id_str;
        row.product_id = drug.product_id;
        row.insurance_code = drug.insurance_code;
        row.dosage = cur.dosage
        row.quantity = cur.quantity;
        row.days = drug.days || '';
        const frequency = frequencyList.value.find(item => item.name === cur.frequencyName);
        row.frequencyName = frequency ? frequency.name : '';
        row.frequencyCode = frequency ? frequency.code : '';
        const usage = usageList.value.find(i => i.name === cur.usageName);
        row.usageName = usage ? usage.name : '';
        row.usageCode = usage ? usage.code : '';
        const unit = unitList.value.find(i => i.code === cur.unit);
        row.unit = unit ? unit.code : '';
        const dosageUnit = dosageUnitList.value.find(i => i.name === cur.dosage_unit);
        row.dosage_unit = dosageUnit ? dosageUnit.name : '';
        row.dosage_unit_code = dosageUnit ? dosageUnit.code : '';
        row.specification = drug.specification || ''
        row.package_amount = drug.package_amount
        row.recommended_quantity = drug.recommended_quantity
        row.usage_restriction_desc = drug.usage_restriction_desc || ''
        row.medication_proof_desc = drug.medication_proof_desc || ''
        row.suitableChild = drug.suitableChild
        row.suitableGender = drug.suitableGender
        row.repeatTag = drug.repeatTag
        acc.push(row)
      } else {
        errorDrugs.push(`患者申请的${cur.name}药品信息不存在或者已下架`);
      }
      return acc
    }, [])
    if (errorDrugs.length) {
      notify = ElNotification({
        title: '药品信息异常',
        dangerouslyUseHTMLString: true,
        duration: 0,
        message: `<div>${errorDrugs.join('<br>')}</div>`,
        type: 'error',
      })
    }
    tabs.value = [{ name: `drug-${Date.now()}`, drugs: _drugs }]
    currentTab.value = tabs.value[0].name;
  } else {
    tabs.value = [{ name: `drug-${Date.now()}`, drugs: [] }]
    currentTab.value = tabs.value[0].name;
  }

}

function clearAll() {
  form.value = { ...initalForm };
  diagnosisList.value = [];
  tabs.value[0].drugs = [];
}

function validateNumber(input, type = 'decimal') {
  const number = Number(input);
  let regex;

  // 根据type决定是校验整数还是小数
  if (type === 'integer') {
    regex = /^[1-9]\d*$/; // 整数，且必须大于0
  } else {
    // 小数，且小数点前必须有至少一个数字，最多支持两位小数
    regex = /^(0(\.\d{1,2})?|[1-9]\d*(\.\d{1,2})?)$/; // 小数，且最多两位小数
  }

  // 校验输入是否符合要求
  if (regex.test(number)) {
    return true;
  } else {
    return false;
  }
}

function previewImage(url) {
  images.value = [url];
  showViewer.value = true;
}

function saveDraft() {
  sessionStorage.setItem(`draftDiagnosis-${consultInfo.value.orderId}`, JSON.stringify({
    form: { ...form.value },
    diagnosisList: diagnosisList.value,
    drugs: tabs.value[0].drugs,
    wines: wines.value
  }))
  ElMessage.success('草稿保存成功')
}
function clearDraft(showTip = false) {
  sessionStorage.removeItem(`draftDiagnosis-${consultInfo.value.orderId}`)
  hasDraft.value = false;
  if (showTip) ElMessage.success('草稿清空成功')
}

const invokeMap = {};
const timerMap = {};

function setCalculateTimer(index) {
  invokeMap[index] = () => calculateQuantity(index);
  if (timerMap[index]) {
    clearTimeout(timerMap[index]);
  }
  timerMap[index] = setTimeout((idx) => {
    if (typeof invokeMap[idx] == 'function') {
      invokeMap[idx]()
      invokeMap[idx] = null
    }
    timerMap[idx] = null;
  }, 750, index);
}

function calculateQuantity(index) {
  const drug = tabs.value[tabIndex.value].drugs[index];
  const recommended_quantity = drug && Number(drug.recommended_quantity) > 0 ? Number(drug.recommended_quantity) : 0;
  if (!drug || !recommended_quantity || drug.autoCalcQuantity === false) return;

  const quantity = Number(drug.quantity) > 0 ? Number(drug.quantity) : 0;
  const dosage = Number(drug.dosage) > 0 ? Number(drug.dosage) : 0;
  const days = Number(drug.days) > 0 ? Number(drug.days) : 0;
  const package_amount = drug.package_amount && Number(drug.package_amount) > 0 ? Number(drug.package_amount) : 0;
  // 判断剂量单位是否参与药品数量的计算 
  const dosageUnit = drug.dosage_unit || '';
  const dosageUnitInCalculate = !excludeCalculateUnit.includes(dosageUnit) && dosageUnitList.value.some(i => i.code == dosageUnit);
  // 判断用药频率是否参与药品数量的计算 
  const frequency = frequencyList.value.find(i => i.code === drug.frequencyCode);
  const frequencyInCalculate = frequency && typeof frequency.number === 'number' && frequency.number > 0;
  // 如果剂量、用药天数、药品包装数量、剂量单位、频次都参与计算，则计算药品数量
  if (dosage > 0 && days > 0 && package_amount > 0 && dosageUnitInCalculate && frequencyInCalculate) {
    const num = Math.round((dosage * days * frequency.number) / package_amount);
    // console.log('计算药品数量: ', num, (dosage * days * frequency.number) / package_amount);
    drug.quantity = Math.max(num, 1);
  } else {
    // 如果不参与计算，则直接使用药品的推荐数量
    drug.quantity = recommended_quantity;
    // console.log('推荐数量: ', num);
  }
  const name = drug.drugName || `第${index + 1}个药品`;
  // console.log('比较: ', drug.quantity, quantity);
  if (drug.quantity != quantity) {
    ElNotification({
      title: '发药数量变化',
      dangerouslyUseHTMLString: true,
      message: `<div>【${name}】的发药数量已自动计算为：<span class="text-red-500 font-semibold">${drug.quantity}${drug.unit || ''}</span>，请核对并确认。</div>`,
      type: 'warning',
    })
  }
}

async function checkStock(drugs) {
  loading.value = true;
  const params = {
    areaCode: props.order.areaCode,
    insuranceCodes: drugs.map(i => i.insurance_code)
  }
  const res = await getHisDrugInfo(params)
  loading.value = false;
  if (res && res.success) {
    const hisDrugs = res.data && Array.isArray(res.data.data) ? res.data.data : [];
    const lackMedicines = drugs.reduce((list, med) => {
      const hisDrug = hisDrugs.find(i => i.gjbm && i.gjbm === med.insurance_code);
      const stock = hisDrug && Number(hisDrug.stock_amount) > 0 ? Number(hisDrug.stock_amount) : 0;
      if (!(stock >= med.quantity)) {
        list.push({ ...med, stock });
      }
      return list;
    }, [])
    if (lackMedicines.length) {
      ElMessageBox.alert(
        `
        <div class="text-gray-500 mb-10px">以下药品库存不足，请调整开药数量：</div>
        ${lackMedicines.map((med, idx) => `
          <div class="text-dark-500 ${idx > 0 ? 'mt-10px' : ''}">
            ${med.drugName}: <span class="ml-2 text-red-500">剩余库存${med.stock}</span>
          </div>
        `).join('')}
        `
        ,
        '提示',
        {
          dangerouslyUseHTMLString: true,
        }
      )
      return Promise.reject('库存不足')
    }

  } else {
    ElMessage.info(res?.message || '查询库存失败')
    return Promise.reject('查询库存失败')
  }

}

async function getConsultProfile() {
  const res = await getConsultOrder({
    page: 1,
    pageSize: 1,
    orderId: props.order.orderId,
    doctorCode: sessionStorage.getItem("doctorNo"),
  });
  getting.value = false;
  const order = res && res.data && res.data.data[0] ? res.data.data[0] : null;
  if (order && order.orderId && order.orderId === props.order.orderId) {
    consultInfo.value = order;
    return order
  }
  consultInfo.value = {};
  ElMessage.error('获取咨询订单失败')
  return null
}

async function getSubmitInterval() {
  const res = await getHlwOrderConfig();
  const config = res && res.data && res.data.data ? res.data.data : {};
  firstSubmitRxIntervel.value = Number.isInteger(config.firstSubmitRxIntervel) && config.firstSubmitRxIntervel > 0 ? config.firstSubmitRxIntervel : 0;
}

async function changeForcePay(index) {
  if (readonly.value) return;
  const item = tabs.value[tabIndex.value].drugs[index];
  item.forceSelfPay = item.forceSelfPay === 'Y' ? 'N' : 'Y';
}

// changeFrequency
watch(() => props.visible, async n => {
  if (n) {
    await nextTick()
    mainRef.value && mainRef.value.scrollTo(0);
    const order = await getConsultProfile();
    if (order) {
      init();
      previewParams.value = {}
      // 开始计时（含回显）
      updatePrescriptionElapsed();
      startPrescriptionTimer();
    } else {
      close();
    }
  } else {
    diagnosisList.value = [];
    tabs.value[0].drugs = [];
    if (notify) {
      notify.close();
      notify = null;
    }
    // 停止计时
    stopPrescriptionTimer();
  }
})

watch([prescriptionStartEffective, prescriptionEndEffective, () => props.visible], () => {
  updatePrescriptionElapsed();
  if (props.visible) {
    if (prescriptionEndEffective.value) {
      stopPrescriptionTimer();
    } else {
      startPrescriptionTimer();
    }
  }
}, { immediate: true })

onMounted(() => {
  updatePrescriptionElapsed();
  if (props.visible && prescriptionStartEffective.value && !prescriptionEndEffective.value) {
    startPrescriptionTimer();
  }
})

onUnmounted(() => {
  stopPrescriptionTimer();
})
</script>
<style lang="scss" scoped>
.prescription-label {
  color: #ff6b00;
}

.prescription-value {
  color: #ff6b00;
}

.drug-spec-line {
  height: 20px;
  padding-top: 4px;
  line-height: 16px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drug-spec-limit {
  margin-left: 5px;
}
</style>
