<script lang="ts" setup>
/**
 * 患者处方记录抽屉：本次 | 历史，支持按订单号/订单ID搜索、展示支付态、复用/撤回
 */
import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import {
  Button,
  Empty,
  Input,
  Spin,
  Tabs,
  Tag,
  message,
} from 'ant-design-vue';

import {
  getPatientPrescriptionHistoryApi,
  getRegisterPrescriptionListApi,
  withdrawPrescriptionApi,
} from '../api';

defineOptions({ name: 'PatientPrescriptionHistoryDrawer' });

const TabPane = Tabs.TabPane;

type DrawerData = {
  registerId?: number;
  userPatientId?: number;
  patientName?: string;
  /** 复用回调：传入处方 id */
  onReuse?: (prescriptionId: number) => void | Promise<void>;
  /** 点击处方号打开详情 */
  onDetail?: (prescriptionId: number) => void;
  /** 是否允许撤回（线下接诊） */
  allowWithdraw?: boolean;
  /** 撤回成功后刷新 */
  onWithdrawn?: () => void;
  /** 医生代支付：打开小程序码 */
  onProxyPay?: (orderId: number) => void;
};

const meta = ref<DrawerData>({});
const loading = ref(false);
const withdrawingId = ref(0);
const listTab = ref<'current' | 'history'>('current');
const keyword = ref('');
const list = ref<Record<string, any>[]>([]);
const page = ref(1);
const hasMore = ref(false);
const pageSize = 20;

const categoryLabel = (c: number) => (Number(c) === 2 ? '医保' : '自费');

const typeLabel = (t: number) => {
  const map: Record<number, string> = {
    1: '中药',
    2: '西药',
    3: '简单产品',
    5: '简单产品',
    6: '简单产品',
    7: '简单产品',
  };
  return map[Number(t)] || `类型${t}`;
};

const payColor = (row: Record<string, any>) => {
  const text = String(row.order_pay_text || '');
  if (text.includes('待支付')) return 'orange';
  if (text.includes('已支付')) return 'green';
  if (text.includes('取消')) return 'default';
  return 'blue';
};

async function loadList(reset = true) {
  if (reset) {
    page.value = 1;
    list.value = [];
  }
  loading.value = true;
  try {
    const kw = keyword.value.trim();
    let res: any;
    if (listTab.value === 'current') {
      const rid = Number(meta.value.registerId || 0);
      if (!rid) {
        list.value = [];
        return;
      }
      res = await getRegisterPrescriptionListApi({
        register_id: rid,
        page: page.value,
        page_size: pageSize,
        keyword: kw || undefined,
      });
    } else {
      const pid = Number(meta.value.userPatientId || 0);
      if (!pid) {
        list.value = [];
        return;
      }
      res = await getPatientPrescriptionHistoryApi({
        patient_id: pid,
        page: page.value,
        page_size: pageSize,
        exclude_register_id: Number(meta.value.registerId || 0) || undefined,
        keyword: kw || undefined,
      });
    }
    const rows = Array.isArray(res?.list) ? res.list : [];
    list.value = reset ? rows : [...list.value, ...rows];
    hasMore.value = !!res?.has_more;
  } catch (e: any) {
    if (reset) list.value = [];
    message.error(e?.message || '加载处方失败');
  } finally {
    loading.value = false;
  }
}

function onSearch() {
  loadList(true);
}

function onTabChange(key: string | number) {
  listTab.value = key === 'history' ? 'history' : 'current';
  loadList(true);
}

function loadMore() {
  if (!hasMore.value || loading.value) return;
  page.value += 1;
  loadList(false);
}

async function handleReuse(row: Record<string, any>) {
  const id = Number(row.id || 0);
  if (!id) return;
  try {
    await meta.value.onReuse?.(id);
  } catch (e: any) {
    message.error(e?.message || '复用失败');
  }
}

/** 点击处方号打开处方详情弹窗 */
function handleOpenDetail(row: Record<string, any>) {
  const id = Number(row.id || 0);
  if (!id) return;
  if (typeof meta.value.onDetail === 'function') {
    meta.value.onDetail(id);
    return;
  }
  message.warning('暂无法打开处方详情');
}

async function handleWithdraw(row: Record<string, any>) {
  const prescriptionId = Number(row.id || 0);
  const registerId = Number(row.register_id || meta.value.registerId || 0);
  if (!prescriptionId || !registerId) return;
  withdrawingId.value = prescriptionId;
  try {
    await withdrawPrescriptionApi({
      prescription_id: prescriptionId,
      register_id: registerId,
    });
    message.success('撤回成功');
    meta.value.onWithdrawn?.();
    await loadList(true);
  } catch (e: any) {
    message.error(e?.message || '撤回失败');
  } finally {
    withdrawingId.value = 0;
  }
}

const titleText = computed(() => {
  const name = meta.value.patientName ? ` - ${meta.value.patientName}` : '';
  return `患者处方记录${name}`;
});

const [Drawer, drawerApi] = useVbenDrawer({
  class: 'w-[820px]',
  title: '患者处方记录',
  cancelText: '关闭',
  showConfirmButton: false,
  onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      meta.value = {};
      list.value = [];
      keyword.value = '';
      listTab.value = 'current';
      page.value = 1;
      return;
    }
    const data = drawerApi.getData<DrawerData>() || {};
    meta.value = data;
    drawerApi.setState({ title: titleText.value });
    loadList(true);
  },
});

defineExpose({ drawerApi });
</script>

<template>
  <Drawer>
    <div class="mb-3 flex flex-wrap items-center gap-2">
      <Input.Search
        v-model:value="keyword"
        allow-clear
        placeholder="按订单号或订单ID搜索"
        style="max-width: 280px"
        @search="onSearch"
      />
      <Button @click="onSearch">查询</Button>
    </div>
    <Tabs :active-key="listTab" @change="onTabChange">
      <TabPane key="current" tab="本次" />
      <TabPane key="history" tab="历史" />
    </Tabs>
    <Spin :spinning="loading">
      <div v-if="list.length === 0 && !loading" class="py-10">
        <Empty description="暂无处方记录" />
      </div>
      <div v-else class="rx-history-list">
        <div
          v-for="row in list"
          :key="row.id"
          class="rx-history-item"
        >
          <div class="rx-history-main">
            <div class="rx-history-title">
              <a
                class="cursor-pointer font-medium text-primary hover:underline"
                title="查看处方详情"
                @click.prevent="handleOpenDetail(row)"
              >
                {{ row.prescription_no || `#${row.id}` }}
              </a>
              <Tag class="ml-2">{{ typeLabel(row.prescription_type) }}</Tag>
              <Tag>{{ categoryLabel(row.category) }}</Tag>
              <Tag :color="payColor(row)">{{ row.order_pay_text || '—' }}</Tag>
              <!-- 医生代支付订单醒目标识（后端 is_proxy_pay / pay_user_type=2） -->
              <Tag
                v-if="row.is_proxy_pay || Number(row.pay_user_type) === 2"
                color="magenta"
              >
                代支付
              </Tag>
            </div>
            <div class="rx-history-meta text-muted-foreground">
              <span>开方时间：{{ row.created_at || '—' }}</span>
              <span class="ml-3">金额：¥{{ row.total_pay_price ?? '—' }}</span>
              <span v-if="row.order_no" class="ml-3">订单号：{{ row.order_no }}</span>
              <span v-if="row.order_id" class="ml-3">订单ID：{{ row.order_id }}</span>
              <span
                v-if="listTab === 'history' && row.register?.order_no"
                class="ml-3"
              >
                挂号：{{ row.register.order_no }}
              </span>
            </div>
          </div>
          <div class="rx-history-actions">
            <Button
              type="link"
              size="small"
              @click="handleReuse(row)"
            >
              复用
            </Button>
            <Button
              v-if="
                listTab === 'current' &&
                row.order_id &&
                (row.can_withdraw ||
                  String(row.order_pay_text || '').includes('待支付') ||
                  Number(row.order_is_pay) === 0)
              "
              type="link"
              size="small"
              @click="meta.onProxyPay?.(Number(row.order_id))"
            >
              代支付
            </Button>
            <Button
              v-if="meta.allowWithdraw && row.can_withdraw && listTab === 'current'"
              type="link"
              size="small"
              danger
              :loading="withdrawingId === row.id"
              @click="handleWithdraw(row)"
            >
              撤回
            </Button>
          </div>
        </div>
        <div v-if="hasMore" class="mt-3 text-center">
          <Button type="link" :loading="loading" @click="loadMore">加载更多</Button>
        </div>
      </div>
    </Spin>
  </Drawer>
</template>

<style scoped>
.rx-history-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: calc(100vh - 260px);
  overflow: auto;
}
.rx-history-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px;
  border: 1px solid hsl(var(--border));
  border-radius: 8px;
}
.rx-history-main {
  min-width: 0;
  flex: 1;
}
.rx-history-title {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  margin-bottom: 6px;
}
.rx-history-meta {
  font-size: 12px;
  line-height: 1.6;
}
.rx-history-actions {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.text-muted-foreground {
  color: hsl(var(--muted-foreground));
}
</style>
