<script lang="ts" setup>
/**
 * 处方详情弹窗
 * - 常规查看：仅展示/打印
 * - auditMode：底部显示「通过审方 / 拒绝」，供药师审方页使用
 */
import { computed, ref } from 'vue';

import { Page, useVbenModal } from '@vben/common-ui';

import { Button, Popover, Select, Spin, Switch, message } from 'ant-design-vue';

import { desktop, isElectron } from '#/util/desktop';
import { getPrescriptionInfoApi } from '#/views/doctor/doctor-reception/api';
import { formatDoctorOrderText } from '#/utils/prescriptionDoctorOrder';
import { formatStoreNameWithHu } from '#/utils/formatStoreNameWithHu';
import { passApi } from '#/views/pharmacist/audit-prescription/api';
import RejectionReason from '#/views/pharmacist/audit-prescription/components/modal.vue';

const item = ref<Record<string, any>>({});
const loading = ref(false);
const passing = ref(false);
/** 药师审方场景标识 */
const auditMode = ref(false);
/** 审核成功后回调（刷新列表） */
const onAudited = ref<(() => void) | null>(null);

/** 顶栏诊所名：在线渠道追加（互）；无诊所名时兜底空串 */
const clinicTitleName = computed(() =>
  formatStoreNameWithHu(
    item.value?.store?.name || item.value?.content?.store?.name || '',
    item.value?.is_online,
  ),
);

/** 是否展示底部审方按钮：审方模式且待审核 */
const showAuditActions = computed(
  () => auditMode.value && Number(item.value?.status) === 0,
);

const [RejectionReasonModal, RejectionReasonModalApi] = useVbenModal({
  connectedComponent: RejectionReason,
});

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  // 默认隐藏确认按钮；审方模式用自定义 footer
  showConfirmButton: false,
  onCancel() {
    modalApi.close();
  },
  onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      item.value = {};
      auditMode.value = false;
      onAudited.value = null;
      loading.value = false;
      passing.value = false;
      return;
    }
    const data = modalApi.getData<Record<string, any>>() || {};
    auditMode.value = !!data.auditMode;
    onAudited.value =
      typeof data.onAudited === 'function' ? data.onAudited : null;
    const { values } = data;
    if (values) {
      if (typeof values === 'number') {
        loading.value = true;
        getPrescriptionInfoApi(values)
          .then((res) => {
            item.value = res || {};
          })
          .finally(() => {
            loading.value = false;
          });
      } else {
        item.value = values;
      }
    }
  },
});

/**
 * 通过审方：调用审核接口，成功后关弹窗并通知父页刷新
 */
/**
 * 通过审方：先回调刷新列表（保留搜索/分页），再关弹窗
 * 必须先 onAudited 再 close，否则 onOpenChange(false) 会清空回调
 */
async function handlePass() {
  const id = item.value?.id;
  if (!id || passing.value) return;
  passing.value = true;
  try {
    await passApi({ id });
    message.success('通过成功');
    const refresh = onAudited.value;
    refresh?.();
    modalApi.close();
  } catch (e) {
    console.error(e);
  } finally {
    passing.value = false;
  }
}

/**
 * 打开拒绝原因弹窗；提交成功后先刷新列表再关闭详情
 */
function handleReject() {
  const id = item.value?.id;
  if (!id) return;
  RejectionReasonModalApi.setData({
    values: id,
    onSuccess: () => {
      const refresh = onAudited.value;
      refresh?.();
      modalApi.close();
    },
  });
  RejectionReasonModalApi.open();
}

/** 是否运行在 Electron 桌面端（决定是否展示打印设置入口与静默打印分支） */
const isDesktop = isElectron();
/** 桌面端打印设置（打印机 + 静默开关），由主进程持久化到本地 */
const printSettings = ref<{ printerName: string; silentPrint: boolean }>({
  printerName: '',
  silentPrint: false,
});
/** 打印机下拉选项（打开设置时从系统实时拉取） */
const printerOptions = ref<Array<{ label: string; value: string }>>([]);
if (isDesktop) {
  desktop.getSettings().then((s) => {
    printSettings.value = s;
  });
}

/** 打开打印设置时拉取系统打印机列表（每次打开都刷新，应对打印机增删） */
async function handlePrintSettingOpen(open: boolean) {
  if (!open) return;
  const printers = await desktop.getPrinters();
  printerOptions.value = printers.map((p) => ({
    label: `${p.displayName || p.name}${p.isDefault ? '（默认）' : ''}`,
    value: p.name,
  }));
}

/** 更新打印设置并持久化（主进程写 userData/desktop-settings.json） */
async function updatePrintSettings(patch: {
  printerName?: string;
  silentPrint?: boolean;
}) {
  printSettings.value = await desktop.setSettings(patch);
}

/**
 * 拼装完整打印 HTML：.print-box 内容 + 页面全部样式（含 scoped 样式与外链样式表）
 * 与 iframe 打印用的是同一套模板内容，保证静默打印与对话框打印效果一致
 */
function buildPrintHtml(fileName: string): null | string {
  const printBox = document.querySelector('.print-box');
  if (!printBox) return null;
  const styleTags: string[] = [];
  document.querySelectorAll('style, link[rel="stylesheet"]').forEach((style) => {
    // link 取绝对地址（.href 属性自动补全），隐藏窗口加载临时文件时才能命中样式
    styleTags.push(
      style.tagName === 'LINK'
        ? `<link rel="stylesheet" href="${(style as HTMLLinkElement).href}" />`
        : style.outerHTML,
    );
  });
  return `<!DOCTYPE html><html><head><meta charset="utf-8" /><title>${fileName || '文档打印'}</title>${styleTags.join('')}</head><body>${printBox.outerHTML}</body></html>`;
}

async function handleWindowPrint(_ele, fileName) {
  // 桌面端且开启静默打印：拼同样的打印 HTML 交给主进程隐藏窗口直接出纸，不弹打印对话框
  if (isDesktop && printSettings.value.silentPrint) {
    const html = buildPrintHtml(fileName);
    if (!html) {
      message.error('找不到打印内容');
      return;
    }
    const result = await desktop.printHTML({
      html,
      deviceName: printSettings.value.printerName || undefined,
      silent: true,
    });
    if (result.ok) {
      message.success('已发送到打印机');
    } else {
      message.error(`打印失败：${result.message || '未知错误'}`);
    }
    return;
  }
  const printBox = document.querySelector('.print-box');
  if (!printBox) {
    console.error('找不到具有 "print-box" 类的元素');
    return;
  }
  const iframe = document.createElement('iframe');
  iframe.style.position = 'fixed';
  iframe.style.right = '0';
  iframe.style.bottom = '0';
  iframe.style.width = '0';
  iframe.style.height = '0';
  iframe.style.border = '0';
  document.body.append(iframe);
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  iframeDoc.open();
  iframeDoc.write(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>${fileName || '文档打印'}</title>
      </head>
      <body>
        ${printBox.outerHTML}
      </body>
    </html>
  `);
  const styles = document.querySelectorAll('style, link[rel="stylesheet"]');
  styles.forEach((style) => {
    if (style.tagName === 'LINK') {
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.href = style.href;
      iframeDoc.head.append(link);
    } else {
      iframeDoc.head.append(style.cloneNode(true));
    }
  });
  iframeDoc.close();
  iframe.contentWindow.addEventListener('load', () => {
    iframe.contentWindow.print();
    setTimeout(() => {
      iframe.remove();
    }, 1000);
  });
}

const decrypt = (str: string) => str;

const getImageSource = (imageString) => {
  if (imageString && imageString.includes('http')) {
    return imageString;
  }
  return `data:image/jpeg;base64,${imageString}`;
};

function parseRecipeContent(content: string | Record<string, unknown>) {
  if (!content) return {};
  if (typeof content === 'string') {
    try {
      return JSON.parse(content);
    } catch {
      return {};
    }
  }
  return content;
}
</script>

<template>
  <Modal class="w-[60%]" title="处方详情">
    <RejectionReasonModal />
    <Spin :spinning="loading">
      <Page>
        <Button type="primary" @click="handleWindowPrint('#demo', '处方')">
          打印处方
        </Button>
        <!-- 打印设置：仅桌面端可见，配置静默打印开关与目标打印机 -->
        <Popover
          v-if="isDesktop"
          trigger="click"
          placement="bottomLeft"
          @open-change="handlePrintSettingOpen"
        >
          <template #content>
            <div class="flex w-64 flex-col gap-3">
              <div class="flex items-center justify-between">
                <span>静默打印</span>
                <Switch
                  :checked="printSettings.silentPrint"
                  @change="
                    (checked: any) =>
                      updatePrintSettings({ silentPrint: !!checked })
                  "
                />
              </div>
              <div>
                <div class="mb-1">打印机</div>
                <Select
                  class="w-full"
                  :value="printSettings.printerName || undefined"
                  :options="printerOptions"
                  placeholder="系统默认打印机"
                  allow-clear
                  @change="
                    (value: any) =>
                      updatePrintSettings({ printerName: (value as string) || '' })
                  "
                />
              </div>
              <div class="text-xs text-muted-foreground">
                开启后打印处方不再弹出打印对话框，直接从所选打印机出纸
              </div>
            </div>
          </template>
          <Button class="ml-2">打印设置</Button>
        </Popover>
        <div class="prescription-container print-box">
          <div class="prescription-header">
            <div class="header-top">
              <span>处方编号: {{ item.prescription_no }}</span>
              <div class="prescription-type">普通处方</div>
            </div>
            <h2 class="clinic-name">{{ clinicTitleName || '诊所' }} 处方笺</h2>
            <div class="prescription-date">开具日期: {{ item.created_at }}</div>
          </div>
          <div class="patient-info">
            <div class="info-row">
              <span>姓名: {{ decrypt(item.content?.patient?.name) }}</span>
              <span>
                性别: {{ item.content?.patient?.sex === 1 ? '男' : '女' }}
              </span>
              <span>年龄: {{ item.content?.patient?.age }}</span>
              <span>类别: {{ item.content?.category }}</span>
            </div>
            <div class="info-row">
              <span>科室: {{ item.content?.doctor?.depart?.name }}</span>
              <span>诊断: {{ item.content?.clinical_diagnose }}</span>
            </div>
            <template v-if="item.online_tcm_print?.show">
              <div v-if="item.online_tcm_print.tcm_syndrome" class="info-row">
                <span>中医证候: {{ item.online_tcm_print.tcm_syndrome }}</span>
              </div>
              <div v-if="item.online_tcm_print.tcm_method" class="info-row">
                <span>中医治法: {{ item.online_tcm_print.tcm_method }}</span>
              </div>
              <div v-if="item.online_tcm_print.tcm_disease" class="info-row">
                <span>中医疾病: {{ item.online_tcm_print.tcm_disease }}</span>
              </div>
            </template>
          </div>
          <div class="medicine-list">
            <div class="rp-title">Rp</div>
            <div
              v-for="(recipe, index) in item.content?.repice"
              :key="index"
              class="recipe-item"
            >
              <div v-if="item.prescription_type === 1" class="w-full">
                <div
                  v-for="drug in JSON.parse(recipe.content)"
                  :key="drug?.id"
                  class="w-1/3"
                  style="display: inline-block"
                >
                  <div class="medicine-item">
                    <span class="drug-name">{{
                      drug?.name || drug?.drug_name
                    }}</span>
                    <span class="drug-quantity mr-5">{{ drug?.number }} /{{ drug?.unit?.name || drug?.use_unit?.name || 'g' }}</span>
                  </div>
                  <div>
                    方法:
                    <span class="preparation-info">{{
                      drug.use_way?.name || drug.useWay || '煎服'
                    }}</span>
                  </div>
                </div>
                <div class="preparation-info">
                  <p>
                    用法:每日{{ recipe.consumption }}次，共{{ recipe.dosage }}剂
                  </p>
                  <p>
                    使用方式：{{
                      `${recipe.process_rule_note}，${recipe.process_rule}`
                    }}
                  </p>
                </div>
              </div>
              <div
                v-else-if="
                  item.prescription_type === 2 ||
                  item.prescription_type === 3 ||
                  item.prescription_type === 5 ||
                  item.prescription_type === 6 ||
                  item.prescription_type === 7
                "
              >
                <template
                  v-for="drug in [parseRecipeContent(recipe.content)]"
                  :key="`west-${index}`"
                >
                  <div class="medicine-item">
                    <span class="drug-name"
                      >{{ drug?.name || drug?.drug_name
                      }}<span
                        v-if="drug?.specification"
                        class="drug-spec"
                        >{{ drug.specification }}</span
                      ></span
                    >
                    <span class="drug-quantity"
                      >{{ drug?.number }}{{ drug?.unit?.name }}</span
                    >
                    <div v-if="drug?.useWay" class="usage-info">
                      {{ drug.useWay }}
                    </div>
                  </div>
                </template>
                <div class="preparation-info">
                  使用方法: {{ recipe.instruction }}
                </div>
              </div>
            </div>
          </div>
          <div class="footer-section">
            <div class="medical-advice">
              <label>医嘱:</label>
              {{ formatDoctorOrderText(item) }}
            </div>
            <div class="signature-area">
              <div class="signature">
                <label>开方医生:</label>
                <img
                  v-if="item.doctor_info?.identity_info?.sign_image"
                  :src="
                    getImageSource(item.doctor_info.identity_info.sign_image)
                  "
                  alt="签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <!-- 二次签名：相冲继续开方时展示第二张医生签名 -->
                <img
                  v-if="
                    item.doctor_second_sign == 1 &&
                    item.doctor_info?.identity_info?.sign_image
                  "
                  :src="
                    getImageSource(item.doctor_info.identity_info.sign_image)
                  "
                  alt="二次签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <span v-else-if="!item.doctor_info?.identity_info?.sign_image">{{
                  item.content?.doctor?.name
                }}</span>
              </div>
              <div class="signature">
                <label>审核药师:</label>
                <img
                  v-if="item.pharmacist_info?.identity?.sign_image"
                  :src="
                    getImageSource(item.pharmacist_info.identity.sign_image)
                  "
                  alt="签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <span v-else>{{ item.pharmacist_info?.name }}</span>
              </div>
              <div class="signature">
                <label>调配人:</label>
                <img
                  v-if="item.doctor_info?.identity_info?.sign_image"
                  :src="
                    getImageSource(item.doctor_info.identity_info.sign_image)
                  "
                  alt="签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <span v-else>{{ item.content?.doctor?.name }}</span>
              </div>
              <div class="signature">
                <label>核对人:</label>
                <img
                  v-if="item.pharmacist_info?.identity?.sign_image"
                  :src="
                    getImageSource(item.pharmacist_info.identity.sign_image)
                  "
                  alt="签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <span v-else>{{ item.pharmacist_info?.name }}</span>
              </div>
              <div class="signature">
                <label>发药人:</label>
                <img
                  v-if="item.doctor_info?.identity_info?.sign_image"
                  :src="
                    getImageSource(item.doctor_info.identity_info.sign_image)
                  "
                  alt="签名"
                  style="width: 120px; height: 50px; display: inline-block"
                />
                <span v-else>{{ item.content?.doctor?.name }}</span>
              </div>
            </div>
            <div class="price-info"></div>
            <div class="price-info">总价: ￥{{ item.total_pay_price }}</div>
            <div
              v-if="item.status === 2"
              class="validity"
              style="color: red; font-weight: bold"
            >
              该处方未通过审核
            </div>
            <div v-else-if="item.auto_expire_txt === ''" class="validity">
              处方有效期: {{ item.valid_hours }}小时
            </div>
            <div v-else class="validity" style="color: red">
              {{ item.auro_expire_txt }}
            </div>
          </div>
        </div>
      </Page>
    </Spin>
    <template v-if="showAuditActions" #footer>
      <div class="flex w-full justify-end gap-2">
        <Button @click="modalApi.close()">取消</Button>
        <Button danger :disabled="passing" @click="handleReject">拒绝</Button>
        <Button type="primary" :loading="passing" @click="handlePass">
          通过审方
        </Button>
      </div>
    </template>
  </Modal>
</template>

<style scoped>
.dark .signature img {
  filter: invert(100%);
}
.prescription-container {
  padding: 20px;
  font-family: 'SimSun', serif;
}
.prescription-header {
  border-bottom: 2px solid #000;
  padding-bottom: 15px;
  margin-bottom: 20px;
}
.header-top {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
}
.prescription-type {
  border: 1px solid #666;
  padding: 2px 8px;
  border-radius: 4px;
}
.clinic-name {
  text-align: center;
  font-size: 24px;
  margin: 15px 0;
}
.prescription-date {
  text-align: right;
}
.patient-info {
  margin-bottom: 20px;
}
.info-row {
  display: flex;
  justify-content: space-between;
  margin: 8px 0;
}
.medicine-list {
  min-height: 200px;
  border-top: 1px dashed #666;
  border-bottom: 1px dashed #666;
  padding: 15px 0;
}
.rp-title {
  font-weight: bold;
  font-size: 18px;
  margin-bottom: 10px;
}
.recipe-item {
  margin-bottom: 15px;
}
.medicine-item {
  display: flex;
  justify-content: space-between;
  margin: 5px 0;
}
.drug-name {
  font-weight: bold;
}
.drug-spec {
  margin-left: 6px;
  font-weight: normal;
  color: #666;
}
.usage-info {
  width: 100%;
  font-size: 12px;
  color: #666;
}
.preparation-info {
  margin-top: 8px;
  color: #333;
}
.footer-section {
  margin-top: 20px;
}
.medical-advice {
  margin-bottom: 15px;
}
.signature-area {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  margin: 15px 0;
}
.signature {
  display: flex;
  align-items: center;
  gap: 8px;
}
.price-info {
  text-align: right;
  font-weight: bold;
  margin-top: 8px;
}
.validity {
  text-align: right;
  margin-top: 8px;
}
</style>
