<script lang="ts" setup>
/**
 * 挂号订单详情弹窗（App 风格分组卡片）
 *
 * 数据来源：列表行数据（后端 list 已带 userPatient/user/store/doctorInfo.depart 关联），
 * 无需再请求详情接口。父级通过 modalApi.setData({ row }) 传入。
 *
 * 展示分组：挂号信息 / 就诊人 / 下单用户 / 诊所 / 医生 / 价格与支付 / 关联处方 / 推广员
 */
import { computed, ref } from 'vue';

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

import { Avatar } from 'ant-design-vue';

import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';
import { pillStyle, tagColorHex } from '#/utils/tagColor';

import {
  REGISTER_PAY_TYPE_MAP,
  REGISTER_REFUND_STATUS_MAP,
  REGISTER_STATUS_MAP,
  REGISTER_TYPE_MAP,
} from '../config/constants';

const emit = defineEmits<{
  /** 点击处方号：由父级打开已有的处方详情弹窗 */
  openPrescription: [prescriptionId: number];
  /** 点击诊所名：由父级打开诊所卡片弹窗 */
  openStore: [storeId: number];
}>();

const row = ref<Record<string, any>>({});

const [Modal, modalApi] = useVbenModal({
  onOpenChange(isOpen) {
    if (isOpen) {
      // 本项目 vben 版本 getData 无泛型签名，取值后显式断言
      const data = modalApi.getData() as Record<string, any> | undefined;
      row.value = data?.row ?? {};
    }
  },
});

const typeMeta = computed(
  () => REGISTER_TYPE_MAP[Number(row.value?.type)] ?? { label: '未知', color: 'default' },
);
const statusMeta = computed(
  () => REGISTER_STATUS_MAP[Number(row.value?.status)] ?? { label: '未知', color: 'default' },
);
const refundMeta = computed(
  () =>
    REGISTER_REFUND_STATUS_MAP[Number(row.value?.refund_status)] ?? {
      label: '未退款',
      color: 'default',
    },
);

/** 性别文案（yii_user_patient.sex：0默认 1男 2女） */
const patientSex = computed(() => {
  const sex = Number(row.value?.userPatient?.sex ?? row.value?.user_patient?.sex);
  if (sex === 1) return '男';
  if (sex === 2) return '女';
  return '—';
});

/** 就诊人/用户/诊所/医生关联兼容 snake_case 序列化（Laravel toArray 默认蛇形） */
const patient = computed(() => row.value?.userPatient ?? row.value?.user_patient ?? {});
const orderUser = computed(() => row.value?.user ?? {});
const store = computed(() => row.value?.store ?? {});
const doctor = computed(() => row.value?.doctorInfo ?? row.value?.doctor_info ?? {});
const departName = computed(() => doctor.value?.depart?.name || '—');
const prescriptions = computed(() =>
  Array.isArray(row.value?.prescription) ? row.value.prescription : [],
);
const salesperson = computed(() => row.value?.salesperson ?? null);

/** 金额格式化：非法值显示占位符 */
function money(value: unknown) {
  const n = Number(value);
  return Number.isFinite(n) ? `¥${n.toFixed(2)}` : '—';
}
</script>

<template>
  <Modal title="挂号详情" class="w-[640px]" :footer="false">
    <div class="rd-body">
      <!-- 顶部概要：订单号 + 状态/方式 -->
      <div class="rd-hero">
        <div class="min-w-0">
          <div class="rd-hero__no">{{ row.order_no || '—' }}</div>
          <div class="rd-hero__time">下单时间：{{ row.created_at || '—' }}</div>
        </div>
        <div class="flex shrink-0 items-center gap-1.5">
          <span class="rd-pill" :style="pillStyle(typeMeta.color)">{{ typeMeta.label }}</span>
          <span class="rd-status" :style="{ color: tagColorHex(statusMeta.color) }">
            <i class="rd-status__dot" :style="{ background: tagColorHex(statusMeta.color) }"></i>
            {{ statusMeta.label }}
          </span>
        </div>
      </div>
      <!-- 就诊人信息 -->
      <div class="rd-section">
        <div class="rd-section__title">就诊人信息</div>
        <div class="rd-grid">
          <div class="rd-item">
            <span class="rd-item__label">姓名</span>
            <span class="rd-item__value">{{ patient.name || '—' }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">性别</span>
            <span class="rd-item__value">{{ patientSex }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">年龄</span>
            <span class="rd-item__value">{{ patient.age ?? '—' }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">手机号</span>
            <span class="rd-item__value">
              <!-- 就诊人手机为敏感字段，统一走 SensitiveText 脱敏/授权查看 -->
              <SensitiveText :record="patient" field="mobile" />
            </span>
          </div>
        </div>
      </div>
      <!-- 下单用户信息 -->
      <div class="rd-section">
        <div class="rd-section__title">用户信息</div>
        <div class="flex items-center gap-3">
          <Avatar :src="orderUser.avatarurl || '/img/user-default-avatar.png'" :size="40" />
          <div class="min-w-0">
            <div class="rd-item__value truncate">{{ orderUser.nickname || '—' }}</div>
            <div class="rd-muted">用户 ID：{{ row.user_id || '—' }}</div>
          </div>
        </div>
      </div>
      <!-- 挂号诊所信息 -->
      <div class="rd-section">
        <div class="rd-section__title">挂号诊所</div>
        <div class="rd-grid rd-grid--single">
          <div class="rd-item">
            <span class="rd-item__label">诊所</span>
            <button
              v-if="store.id"
              type="button"
              class="rd-link"
              @click="emit('openStore', Number(store.id))"
            >
              {{ store.name || '—' }}
            </button>
            <span v-else class="rd-item__value">{{ store.name || '—' }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">地址</span>
            <span class="rd-item__value">{{ store.position || '—' }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">电话</span>
            <span class="rd-item__value">{{ store.mobile || '—' }}</span>
          </div>
        </div>
      </div>
      <!-- 医生信息 -->
      <div class="rd-section">
        <div class="rd-section__title">医生信息</div>
        <div class="flex items-center gap-3">
          <Avatar :src="doctor.avatar || '/img/user-default-avatar.png'" :size="40" />
          <div class="min-w-0 flex-1">
            <div class="rd-item__value truncate">{{ doctor.name || '—' }}</div>
            <div class="rd-muted">科室：{{ departName }}</div>
          </div>
          <div class="rd-muted shrink-0">挂号序号 #{{ row.order_number ?? '—' }}</div>
        </div>
      </div>
      <!-- 价格与支付 -->
      <div class="rd-section">
        <div class="rd-section__title">价格与支付</div>
        <div class="rd-grid">
          <div class="rd-item">
            <span class="rd-item__label">挂号金额</span>
            <span class="rd-item__value rd-item__value--price">{{ money(row.price) }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">支付状态</span>
            <span class="rd-pill" :style="pillStyle(row.is_pay === 1 ? 'green' : 'red')">
              {{ row.is_pay === 1 ? '已支付' : '未支付' }}
            </span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">支付方式</span>
            <span class="rd-item__value">
              {{ row.is_pay === 1 ? REGISTER_PAY_TYPE_MAP[Number(row.pay_type)] || '—' : '—' }}
            </span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">支付时间</span>
            <span class="rd-item__value">{{ row.pay_time || '未支付' }}</span>
          </div>
          <div class="rd-item">
            <span class="rd-item__label">退款状态</span>
            <span class="rd-pill" :style="pillStyle(refundMeta.color)">
              {{ refundMeta.label }}
            </span>
          </div>
          <div v-if="Number(row.refund_status) === 3" class="rd-item">
            <span class="rd-item__label">退款时间</span>
            <span class="rd-item__value">{{ row.refund_time || '—' }}</span>
          </div>
        </div>
        <!-- 取消/拒诊补充信息（有才显示） -->
        <div v-if="row.cancel_status === 1 || row.refuse_reason" class="rd-extra">
          <div v-if="row.cancel_status === 1">
            已取消：{{ row.cancel_time || '—' }}
            <template v-if="row.cancel_remark">（{{ row.cancel_remark }}）</template>
          </div>
          <div v-if="row.refuse_reason">拒诊原因：{{ row.refuse_reason }}</div>
        </div>
      </div>
      <!-- 关联处方（有才显示） -->
      <div v-if="prescriptions.length" class="rd-section">
        <div class="rd-section__title">关联处方</div>
        <div class="flex flex-wrap gap-2">
          <button
            v-for="item in prescriptions"
            :key="item.id"
            type="button"
            class="rd-link rd-link--chip"
            @click="emit('openPrescription', Number(item.id))"
          >
            {{ item.prescription_no }}
          </button>
        </div>
      </div>
      <!-- 推广员（有才显示） -->
      <div v-if="salesperson?.id" class="rd-section">
        <div class="rd-section__title">推广员</div>
        <div class="flex items-center gap-3">
          <Avatar :src="salesperson.avatar || '/img/user-default-avatar.png'" :size="32" />
          <span class="rd-item__value">{{ salesperson.nick_name || '—' }}</span>
        </div>
      </div>
    </div>
  </Modal>
</template>

<style scoped>
.rd-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 4px;
}

/* 顶部概要条（Apple 风格：浅灰内嵌块，无边框） */
.rd-hero {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  background: hsl(var(--muted) / 35%);
  border-radius: 14px;
}

.rd-hero__no {
  overflow: hidden;
  font-size: 15px;
  font-weight: 600;
  color: hsl(var(--foreground));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rd-hero__time {
  margin-top: 2px;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

/* 分组块：Apple 设置页风格，浅灰内嵌圆角块 + 小节标题（禁止左侧竖色条） */
.rd-section {
  padding: 12px 14px;
  background: hsl(var(--muted) / 25%);
  border-radius: 14px;
}

.rd-section__title {
  margin-bottom: 10px;
  font-size: 12px;
  font-weight: 600;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* 两列信息栅格 */
.rd-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 16px;
}

.rd-grid--single {
  grid-template-columns: 1fr;
}

.rd-item {
  display: flex;
  gap: 8px;
  align-items: baseline;
  min-width: 0;
  font-size: 13px;
}

.rd-item__label {
  flex-shrink: 0;
  color: hsl(var(--muted-foreground));
}

.rd-item__value {
  min-width: 0;
  overflow: hidden;
  color: hsl(var(--foreground));
  text-overflow: ellipsis;
}

.rd-item__value--price {
  font-size: 15px;
  font-weight: 700;
}

.rd-muted {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

.rd-link {
  padding: 0;
  font-size: 13px;
  color: hsl(var(--primary));
  cursor: pointer;
  background: none;
  border: none;
}

.rd-link:hover {
  text-decoration: underline;
}

.rd-link--chip {
  padding: 3px 10px;
  background: hsl(var(--primary) / 8%);
  border: 1px solid hsl(var(--primary) / 25%);
  border-radius: 8px;
}

.rd-link--chip:hover {
  text-decoration: none;
  box-shadow: 0 0 6px hsl(var(--primary) / 18%);
}

/* tinted 胶囊 / 状态彩点（与订单卡片同一套 Apple 语言） */
.rd-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  font-size: 11px;
  font-weight: 500;
  line-height: 18px;
  border-radius: 999px;
}

.rd-status {
  display: inline-flex;
  gap: 5px;
  align-items: center;
  font-size: 13px;
  font-weight: 600;
}

.rd-status__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.rd-extra {
  padding: 8px 10px;
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.8;
  color: hsl(var(--warning, 38 92% 50%));
  background: hsl(var(--warning, 38 92% 50%) / 10%);
  border-radius: 8px;
}
</style>
