<script lang="ts" setup>
/**
 * 患者详情弹窗组件
 *
 * @description 展示患者的详细信息
 *              - 基本信息、备注、分组
 *              - 挂号记录列表
 *              - 处方记录列表
 * @author 系统
 * @date 2024
 */
import { h, ref } from 'vue';

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

import {
  Avatar,
  Button,
  Card,
  Col,
  Descriptions,
  Empty,
  Input,
  message,
  Row,
  Spin,
  Table,
  Tabs,
  TabPane,
  Tag,
} from 'ant-design-vue';
import { UserOutlined } from '@ant-design/icons-vue';

import PrescriptionDetail from '#/views/doctor/doctor-reception/components/PrescriptionDetail.vue';

import {
  getPatientDetailApi,
  getPatientRegisterListApi,
  getPatientPrescriptionListApi,
  getPatientBaseInfoApi,
  savePatientRemarkApi,
  updatePatientRemarkApi,
  type PatientDetail,
  type RegisterItem,
  type PrescriptionItem,
} from '../api';

// ==================== 类型定义 ====================

/**
 * 健康信息类型
 */
interface UserPatientHealthInquiry {
  id: number;
  user_patient_id: number;
  liver_function: number;
  renal_function: number;
  liver_index: string;
  renal_index: string;
  person_history: string;
  allergic_history: string;
  person_status: number;
  allergic_status: number;
  family_status: number;
  family_history: string;
  is_delete: number;
}

// ==================== 响应式数据 ====================

/**
 * 患者ID
 */
const patientId = ref(0);

/**
 * 患者姓名
 */
const patientName = ref('');

/**
 * 患者详情数据
 */
const patientDetail = ref<PatientDetail | null>(null);

/**
 * 挂号记录列表
 */
const registerList = ref<RegisterItem[]>([]);

/**
 * 处方记录列表
 */
const prescriptionList = ref<PrescriptionItem[]>([]);

/**
 * 加载状态
 */
const loading = ref(false);

/**
 * 挂号记录加载状态
 */
const registerLoading = ref(false);

/**
 * 处方记录加载状态
 */
const prescriptionLoading = ref(false);

/**
 * 当前激活的Tab
 */
const activeTab = ref('info');

/**
 * 备注编辑模式
 */
const remarkEditing = ref(false);

/**
 * 备注内容
 */
const remarkContent = ref('');

/**
 * 是否已有备注
 */
const hasRemark = ref(false);

/**
 * 健康信息数据
 */
const healthInfo = ref<UserPatientHealthInquiry | null>(null);

// ==================== 处方详情弹窗 ====================

const [PrescriptionDetailModal, PrescriptionDetailModalApi] = useVbenModal({
  connectedComponent: PrescriptionDetail,
});

/**
 * 打开处方详情
 * @param prescriptionId 处方ID
 */
function openPrescriptionDetail(prescriptionId: number) {
  PrescriptionDetailModalApi.setData({ values: prescriptionId });
  PrescriptionDetailModalApi.open();
}

/**
 * 分割字符串为数组
 * @param str 逗号分隔的字符串
 */
function splitString(str: string): string[] {
  if (!str) return [];
  return str.split(',').filter((item) => item.trim());
}

// ==================== 表格列配置 ====================

/**
 * 格式化挂号价格
 */
function formatRegisterPrice(price: unknown) {
  const n = Number(price);
  if (!Number.isFinite(n)) {
    return '—';
  }
  return `¥${n.toFixed(2)}`;
}

/**
 * 挂号记录表格列
 */
const registerColumns = [
  { title: '订单编号', dataIndex: 'order_no', key: 'order_no' },
  { title: '医生', dataIndex: 'doctor', key: 'doctor' },
  { title: '诊所', dataIndex: 'store', key: 'store' },
  {
    title: '费用',
    dataIndex: 'price',
    key: 'price',
    customRender: ({ text }: { text: number }) => formatRegisterPrice(text),
  },
  {
    title: '是否支付',
    dataIndex: 'is_pay',
    key: 'is_pay',
    customRender: ({ text }: { text: number }) =>
      h(
        Tag,
        { color: text === 1 ? 'green' : 'red' },
        () => (text === 1 ? '已支付' : '未支付'),
      ),
  },
  {
    title: '状态',
    dataIndex: 'status_text',
    key: 'status_text',
  },
  { title: '创建时间', dataIndex: 'created_at', key: 'created_at' },
];

/**
 * 处方记录表格列
 */
const prescriptionColumns = [
  {
    title: '处方编号',
    dataIndex: 'prescription_no',
    key: 'prescription_no',
    customRender: ({ text, record }: { text: string; record: PrescriptionItem }) => {
      return h(
        Button,
        {
          type: 'link',
          onClick: () => openPrescriptionDetail(record.id),
        },
        () => text,
      );
    },
  },
  {
    title: '类型',
    dataIndex: 'prescription_type',
    key: 'prescription_type',
    customRender: ({ text }: { text: number }) => {
      const typeMap: Record<number, string> = {
        1: '中药处方',
        2: '西药处方',
        5: '服务包',
      };
      return typeMap[text] || '未知';
    },
  },
  { title: '诊断', dataIndex: 'clinical_diagnose', key: 'clinical_diagnose' },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
    customRender: ({ text }: { text: number }) => {
      const statusMap: Record<number, string> = {
        0: '待审核',
        1: '已通过',
        2: '未通过',
        3: '无需审核',
      };
      return statusMap[text] || '未知';
    },
  },
  { title: '创建时间', dataIndex: 'created_at', key: 'created_at' },
];

// ==================== Modal 配置 ====================

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  footer: false,
  onCancel() {
    modalApi.close();
  },
  onOpenChange(isOpen: boolean) {
    if (isOpen) {
      const data = modalApi.getData<{
        patientId: number;
        patientName: string;
      }>();

      if (data) {
        patientId.value = data.patientId;
        patientName.value = data.patientName;
        activeTab.value = 'info';
        loadPatientDetail();
      }
    }
  },
});

// ==================== 方法定义 ====================

/**
 * 加载患者详情
 */
async function loadPatientDetail() {
  loading.value = true;
  try {
    const res = await getPatientDetailApi(patientId.value);
    patientDetail.value = res;
    remarkContent.value = res.remark || '';
    hasRemark.value = !!res.remark;
    // 同时加载健康信息
    loadHealthInfo();
  } catch (error) {
    console.error('获取患者详情失败:', error);
    message.error('获取患者详情失败');
  } finally {
    loading.value = false;
  }
}

/**
 * 加载健康信息
 */
async function loadHealthInfo() {
  try {
    const res = await getPatientBaseInfoApi(patientId.value);
    healthInfo.value = res || null;
  } catch (error) {
    console.error('获取健康信息失败:', error);
    healthInfo.value = null;
  }
}

/**
 * 加载挂号记录
 */
async function loadRegisterList() {
  registerLoading.value = true;
  try {
    const res = await getPatientRegisterListApi(patientId.value);
    registerList.value = res.items || [];
  } catch (error) {
    console.error('获取挂号记录失败:', error);
    message.error('获取挂号记录失败');
  } finally {
    registerLoading.value = false;
  }
}

/**
 * 加载处方记录
 */
async function loadPrescriptionList() {
  prescriptionLoading.value = true;
  try {
    const res = await getPatientPrescriptionListApi(patientId.value);
    prescriptionList.value = res.items || [];
  } catch (error) {
    console.error('获取处方记录失败:', error);
    message.error('获取处方记录失败');
  } finally {
    prescriptionLoading.value = false;
  }
}

/**
 * Tab切换处理
 * @param key Tab键值
 */
function handleTabChange(key: string) {
  activeTab.value = key;
  if (key === 'register' && registerList.value.length === 0) {
    loadRegisterList();
  } else if (key === 'prescription' && prescriptionList.value.length === 0) {
    loadPrescriptionList();
  }
}

/**
 * 保存备注
 */
async function saveRemark() {
  if (!remarkContent.value.trim()) {
    message.warning('请输入备注内容');
    return;
  }

  try {
    if (hasRemark.value) {
      await updatePatientRemarkApi(patientId.value, remarkContent.value);
    } else {
      await savePatientRemarkApi(patientId.value, remarkContent.value);
    }
    message.success('备注保存成功');
    remarkEditing.value = false;
    hasRemark.value = true;
    // 刷新详情
    loadPatientDetail();
  } catch (error) {
    console.error('保存备注失败:', error);
    message.error('保存备注失败');
  }
}

/**
 * 获取性别文字
 * @param sex 性别值
 */
function getSexText(sex: number): string {
  return sex === 1 ? '男' : sex === 2 ? '女' : '未知';
}
</script>

<template>
  <Modal class="w-[70%]" :title="`患者详情 - ${patientName}`">
    <Page>
      <Spin :spinning="loading">
        <Tabs v-model:activeKey="activeTab" @change="handleTabChange">
          <!-- 基本信息 -->
          <TabPane key="info" tab="基本信息">
            <div v-if="patientDetail">
              <Row :gutter="24">
                <!-- 左侧：头像和基本信息 -->
                <Col :span="8">
                  <Card>
                    <div class="text-center">
                      <Avatar :size="100" :src="patientDetail.avatar">
                        <template #icon><UserOutlined /></template>
                      </Avatar>
                      <h3 class="mt-4 text-xl font-bold">
                        {{ patientDetail.patient?.name }}
                      </h3>
                      <div class="mt-2">
                        <Tag
                          :color="
                            patientDetail.patient?.sex === 1
                              ? '#1890ff'
                              : '#eb2f96'
                          "
                        >
                          {{ getSexText(patientDetail.patient?.sex) }}
                        </Tag>
                        <Tag color="blue">{{ patientDetail.age }}岁</Tag>
                      </div>
                    </div>
                  </Card>
                </Col>

                <!-- 右侧：详细信息 -->
                <Col :span="16">
                  <Card title="患者信息">
                    <Descriptions :column="2" bordered>
                      <Descriptions.Item label="姓名">
                        {{ patientDetail.patient?.name }}
                      </Descriptions.Item>
                      <Descriptions.Item label="性别">
                        {{ getSexText(patientDetail.patient?.sex) }}
                      </Descriptions.Item>
                      <Descriptions.Item label="年龄">
                        {{ patientDetail.age }}岁
                      </Descriptions.Item>
                      <Descriptions.Item label="手机号">
                        {{ patientDetail.patient?.mobile || '未填写' }}
                      </Descriptions.Item>
                      <Descriptions.Item label="身份证" :span="2">
                        {{ patientDetail.patient?.id_card || '未填写' }}
                      </Descriptions.Item>
                    </Descriptions>
                  </Card>

                  <!-- 分组信息 -->
                  <Card title="分组信息" class="mt-4">
                    <div
                      v-if="
                        Array.isArray(patientDetail.group) &&
                        patientDetail.group.length > 0
                      "
                    >
                      <Tag
                        v-for="item in patientDetail.group"
                        :key="item.id"
                        color="blue"
                        class="mr-2 mb-2"
                      >
                        {{ item.name }}
                      </Tag>
                    </div>
                    <Empty v-else description="暂无分组" />
                  </Card>

                  <!-- 备注信息 -->
                  <Card title="备注" class="mt-4">
                    <div v-if="!remarkEditing">
                      <p v-if="patientDetail.remark">
                        {{ patientDetail.remark }}
                      </p>
                      <Empty v-else description="暂无备注" />
                      <Button
                        type="primary"
                        size="small"
                        class="mt-2"
                        @click="remarkEditing = true"
                      >
                        {{ hasRemark ? '编辑备注' : '添加备注' }}
                      </Button>
                    </div>
                    <div v-else>
                      <Input.TextArea
                        v-model:value="remarkContent"
                        :rows="4"
                        placeholder="请输入备注内容"
                      />
                      <div class="mt-2">
                        <Button
                          type="primary"
                          size="small"
                          @click="saveRemark"
                        >
                          保存
                        </Button>
                        <Button
                          size="small"
                          class="ml-2"
                          @click="remarkEditing = false"
                        >
                          取消
                        </Button>
                      </div>
                    </div>
                  </Card>

                  <!-- 健康信息 -->
                  <Card title="健康信息" class="mt-4">
                    <Descriptions
                      v-if="healthInfo"
                      :column="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 2 }"
                      bordered
                    >
                      <Descriptions.Item label="肝功能">
                        <span>{{
                          healthInfo.liver_function === 0 ? '正常' : '异常'
                        }}</span>
                        <p
                          v-if="healthInfo.liver_function === 1"
                          class="mt-3"
                        >
                          <Tag
                            v-for="item in splitString(healthInfo.liver_index)"
                            :key="item"
                            color="#455cda"
                          >
                            {{ item }}
                          </Tag>
                        </p>
                      </Descriptions.Item>
                      <Descriptions.Item label="肾功能">
                        <span>{{
                          healthInfo.renal_function === 0 ? '正常' : '异常'
                        }}</span>
                        <p
                          v-if="healthInfo.renal_function === 1"
                          class="mt-3"
                        >
                          <Tag
                            v-for="item in splitString(healthInfo.renal_index)"
                            :key="item"
                            color="#455cda"
                          >
                            {{ item }}
                          </Tag>
                        </p>
                      </Descriptions.Item>
                      <Descriptions.Item label="既往史">
                        <span>{{
                          healthInfo.person_status === 0 ? '无' : '有'
                        }}</span>
                        <p v-if="healthInfo.person_status === 1" class="mt-3">
                          <Tag
                            v-for="item in splitString(healthInfo.person_history)"
                            :key="item"
                            color="#455cda"
                          >
                            {{ item }}
                          </Tag>
                        </p>
                      </Descriptions.Item>
                      <Descriptions.Item label="过敏史">
                        <span>{{
                          healthInfo.allergic_status === 0 ? '无' : '有'
                        }}</span>
                        <p
                          v-if="healthInfo.allergic_status === 1"
                          class="mt-3"
                        >
                          <Tag
                            v-for="item in splitString(healthInfo.allergic_history)"
                            :key="item"
                            color="#455cda"
                          >
                            {{ item }}
                          </Tag>
                        </p>
                      </Descriptions.Item>
                      <Descriptions.Item label="家庭遗传史">
                        <span>{{
                          healthInfo.family_status === 0 ? '无' : '有'
                        }}</span>
                        <p v-if="healthInfo.family_status === 1" class="mt-3">
                          <Tag
                            v-for="item in splitString(String(healthInfo.family_history))"
                            :key="item"
                            color="#455cda"
                          >
                            {{ item }}
                          </Tag>
                        </p>
                      </Descriptions.Item>
                    </Descriptions>
                    <Empty v-else description="暂无健康信息" />
                  </Card>
                </Col>
              </Row>
            </div>
            <Empty v-else description="暂无数据" />
          </TabPane>

          <!-- 挂号记录 -->
          <TabPane key="register" tab="挂号记录">
            <Spin :spinning="registerLoading">
              <Table
                :columns="registerColumns"
                :data-source="registerList"
                :pagination="false"
                row-key="id"
              >
                <template #emptyText>
                  <Empty description="暂无挂号记录" />
                </template>
              </Table>
            </Spin>
          </TabPane>

          <!-- 处方记录 -->
          <TabPane key="prescription" tab="处方记录">
            <Spin :spinning="prescriptionLoading">
              <Table
                :columns="prescriptionColumns"
                :data-source="prescriptionList"
                :pagination="false"
                row-key="id"
              >
                <template #emptyText>
                  <Empty description="暂无处方记录" />
                </template>
              </Table>
            </Spin>
          </TabPane>
        </Tabs>
      </Spin>
    </Page>
  </Modal>
  <PrescriptionDetailModal />
</template>

<style lang="scss" scoped>
:deep(.ant-descriptions-item-label) {
  width: 100px;
}
</style>

