<script lang="ts" setup>
/**
 * 医生新建就诊人：基础信息 + 健康信息（与患者小程序 myinfo-add 对齐）+ 可选免除挂号费
 * 健康信息采用「有/无 + 标签多选（可自定义）」交互，提交后自动挂号
 */
import { computed, ref } from 'vue';

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

import {
  Col,
  DatePicker,
  Form,
  FormItem,
  Input,
  InputNumber,
  message,
  Radio,
  RadioGroup,
  Row,
  Select,
  Switch,
} from 'ant-design-vue';
import dayjs, { type Dayjs } from 'dayjs';

import { createUserPatientApi } from '#/views/doctor/doctor-reception/api';
import {
  ALLERGIC_HISTORY_OPTIONS,
  EPIDEMIC_HISTORY_OPTIONS,
  FAMILY_HISTORY_OPTIONS,
  HISTORY_STATUS_OPTIONS,
  LIVER_RENAL_OPTIONS,
  MARITAL_HISTORY_OPTIONS,
  MENSTRUAL_HISTORY_OPTIONS,
  PERSON_HISTORY_OPTIONS,
  PERSONAL_HISTORY_OPTIONS,
  PRESENT_HISTORY_OPTIONS,
} from '#/views/doctor/doctor-reception/config/health-history';

/** 创建成功回传：含 register_id / user_patient_id / is_pay，供接诊页分情况引导 */
export type CreateUserPatientResult = {
  user_patient_id: number;
  register_id: number;
  waive_register_fee: number;
  price: string;
  is_pay: number;
};

/** 健康史字段名（status 与 history 成对） */
type HistoryKey =
  | 'allergic'
  | 'present'
  | 'person'
  | 'family'
  | 'epidemic'
  | 'personal'
  | 'menstrual'
  | 'marital';

const submitting = ref(false);
const form = ref(buildEmptyForm());
const onSuccessCb = ref<null | ((res: CreateUserPatientResult) => void)>(null);

/** ≤6 岁需填监护人（与小程序、后端 UnclaimedPatientService 一致） */
const showGuardian = computed(() => Number(form.value.age) > 0 && Number(form.value.age) <= 6);

/** 月经史仅女性展示 */
const showMenstrualHistory = computed(() => Number(form.value.sex) === 2);

/** 婚育史：男>22 或 女>20 */
const showMaritalHistory = computed(() => {
  const age = Number(form.value.age) || 0;
  const sex = Number(form.value.sex);
  return (sex === 1 && age > 22) || (sex === 2 && age > 20);
});

function buildEmptyForm() {
  return {
    name: '',
    id_card: '',
    birthday: '' as string,
    sex: 1,
    age: undefined as number | undefined,
    mobile: '',
    relation: 7,
    waive_register_fee: true,
    liver_function: 0,
    renal_function: 0,
    liver_index: '',
    renal_index: '',
    person_status: 0,
    allergic_status: 0,
    family_status: 0,
    epidemic_status: 0,
    personal_status: 0,
    menstrual_status: 0,
    marital_status: 0,
    present_status: 0,
    // history 用字符串数组，与小程序提交结构一致，后端会逗号拼接
    person_history: [] as string[],
    allergic_history: [] as string[],
    family_history: [] as string[],
    epidemic_history: [] as string[],
    personal_history: [] as string[],
    menstrual_history: [] as string[],
    marital_history: [] as string[],
    present_history: [] as string[],
    guardian_name: '',
    guardian_id_card: '',
    guardian_mobile: '',
    guardian_relation: 0,
  };
}

const relationOptions = [
  { label: '本人', value: 0 },
  { label: '丈夫', value: 1 },
  { label: '妻子', value: 2 },
  { label: '爸爸', value: 3 },
  { label: '妈妈', value: 4 },
  { label: '儿子', value: 5 },
  { label: '女儿', value: 6 },
  { label: '其他', value: 7 },
];

/** 各类史：status 字段名 + history 字段名 + 预设选项 */
const historyBlocks: Array<{
  key: HistoryKey;
  label: string;
  statusField: keyof ReturnType<typeof buildEmptyForm>;
  historyField: keyof ReturnType<typeof buildEmptyForm>;
  options: Array<{ label: string; value: string }>;
  visible: () => boolean;
}> = [
  {
    key: 'allergic',
    label: '过敏史',
    statusField: 'allergic_status',
    historyField: 'allergic_history',
    options: ALLERGIC_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'present',
    label: '现病史',
    statusField: 'present_status',
    historyField: 'present_history',
    options: PRESENT_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'person',
    label: '既往史',
    statusField: 'person_status',
    historyField: 'person_history',
    options: PERSON_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'family',
    label: '家族史',
    statusField: 'family_status',
    historyField: 'family_history',
    options: FAMILY_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'epidemic',
    label: '流行病学史',
    statusField: 'epidemic_status',
    historyField: 'epidemic_history',
    options: EPIDEMIC_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'personal',
    label: '个人史',
    statusField: 'personal_status',
    historyField: 'personal_history',
    options: PERSONAL_HISTORY_OPTIONS,
    visible: () => true,
  },
  {
    key: 'menstrual',
    label: '月经史',
    statusField: 'menstrual_status',
    historyField: 'menstrual_history',
    options: MENSTRUAL_HISTORY_OPTIONS,
    visible: () => showMenstrualHistory.value,
  },
  {
    key: 'marital',
    label: '婚育史',
    statusField: 'marital_status',
    historyField: 'marital_history',
    options: MARITAL_HISTORY_OPTIONS,
    visible: () => showMaritalHistory.value,
  },
];

/**
 * 切换「有/无」时清空标签，避免 status=无 仍带上旧标签
 */
function onHistoryStatusChange(
  statusField: keyof ReturnType<typeof buildEmptyForm>,
  historyField: keyof ReturnType<typeof buildEmptyForm>,
  status: number,
) {
  (form.value[statusField] as number) = status;
  if (status === 0) {
    (form.value[historyField] as string[]) = [];
  }
}

/** 读取某条史的标签数组（模板里避免复杂断言） */
function getHistoryTags(historyField: keyof ReturnType<typeof buildEmptyForm>): string[] {
  return (form.value[historyField] as string[]) || [];
}

/** 写入某条史的标签数组 */
function setHistoryTags(historyField: keyof ReturnType<typeof buildEmptyForm>, tags: string[]) {
  (form.value[historyField] as string[]) = tags || [];
}

/**
 * 组装提交体：不展示的月经/婚育强制清零；history 仅在 status=有 时带出
 */
function buildSubmitPayload() {
  const f = form.value;
  const menstrualOk = showMenstrualHistory.value;
  const maritalOk = showMaritalHistory.value;
  return {
    ...f,
    waive_register_fee: f.waive_register_fee ? 1 : 0,
    menstrual_status: menstrualOk ? f.menstrual_status : 0,
    menstrual_history: menstrualOk && f.menstrual_status === 1 ? f.menstrual_history : [],
    marital_status: maritalOk ? f.marital_status : 0,
    marital_history: maritalOk && f.marital_status === 1 ? f.marital_history : [],
    allergic_history: f.allergic_status === 1 ? f.allergic_history : [],
    present_history: f.present_status === 1 ? f.present_history : [],
    person_history: f.person_status === 1 ? f.person_history : [],
    family_history: f.family_status === 1 ? f.family_history : [],
    epidemic_history: f.epidemic_status === 1 ? f.epidemic_history : [],
    personal_history: f.personal_status === 1 ? f.personal_history : [],
  };
}

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  // 健康信息字段较多，限制内容区高度可滚动，避免弹窗撑出视口
  contentClass: 'max-h-[70vh] overflow-y-auto',
  onCancel() {
    modalApi.close();
  },
  async onConfirm() {
    if (!form.value.name?.trim()) {
      message.error('请填写姓名');
      return;
    }
    if (!form.value.mobile || !/^\d{11}$/.test(form.value.mobile)) {
      message.error('请填写正确手机号');
      return;
    }
    if (!form.value.id_card && !form.value.birthday) {
      message.error('请填写身份证或生日');
      return;
    }
    if (form.value.age == null || form.value.age < 1) {
      message.error('请填写年龄');
      return;
    }
    if (showGuardian.value) {
      if (!form.value.guardian_name || !form.value.guardian_id_card || !form.value.guardian_mobile) {
        message.error('6岁及以下请填写监护人信息');
        return;
      }
    }
    submitting.value = true;
    modalApi.setState({ confirmLoading: true });
    try {
      const res = await createUserPatientApi(buildSubmitPayload());
      message.success('创建成功，已自动挂号');
      // 先回调再关窗：父级按 is_pay 决定选中列表或弹认领码
      onSuccessCb.value?.(res as CreateUserPatientResult);
      modalApi.close();
    } catch (e: any) {
      message.error(e?.message || '创建失败');
    } finally {
      submitting.value = false;
      modalApi.setState({ confirmLoading: false });
    }
  },
  onOpenChange(isOpen: boolean) {
    if (isOpen) {
      form.value = buildEmptyForm();
      const data =
        modalApi.getData<{
          onSuccess?: (res: CreateUserPatientResult) => void;
        }>() || {};
      onSuccessCb.value = data.onSuccess || null;
    }
  },
});

/** 生日选择回填（value-format 时 change 直接给字符串） */
function onBirthdayChange(v: Dayjs | string | null) {
  if (!v) {
    form.value.birthday = '';
    return;
  }
  const str = typeof v === 'string' ? v : v.format('YYYY-MM-DD');
  form.value.birthday = str;
  form.value.age = dayjs().diff(dayjs(str), 'year');
}
</script>

<template>
  <Modal class="w-[800px]" title="新建就诊人">
    <Form layout="vertical" class="create-user-patient-form">
      <div class="mb-3 text-sm font-medium text-[hsl(var(--foreground))]">基础信息</div>
      <Row :gutter="12">
        <Col :span="12">
          <FormItem label="姓名" required>
            <Input v-model:value="form.name" placeholder="真实姓名" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="手机号" required>
            <Input v-model:value="form.mobile" maxlength="11" placeholder="11位手机号" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="身份证号">
            <Input v-model:value="form.id_card" maxlength="18" placeholder="选填" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="生日" required>
            <DatePicker
              class="w-full"
              :value="form.birthday ? dayjs(form.birthday) : undefined"
              value-format="YYYY-MM-DD"
              placeholder="请选择"
              @change="onBirthdayChange"
            />
          </FormItem>
        </Col>
        <Col :span="8">
          <FormItem label="性别" required>
            <RadioGroup v-model:value="form.sex">
              <Radio :value="1">男</Radio>
              <Radio :value="2">女</Radio>
            </RadioGroup>
          </FormItem>
        </Col>
        <Col :span="8">
          <FormItem label="年龄" required>
            <InputNumber v-model:value="form.age" class="w-full" :min="1" :max="200" />
          </FormItem>
        </Col>
        <Col :span="8">
          <FormItem label="关系">
            <Select v-model:value="form.relation" :options="relationOptions" />
          </FormItem>
        </Col>
        <Col :span="24">
          <FormItem label="免除挂号费">
            <Switch v-model:checked="form.waive_register_fee" checked-children="免除" un-checked-children="收取" />
            <span class="ml-2 text-xs text-[hsl(var(--muted-foreground))]">
              开启后挂号费为 0 且标记已支付，可直接接诊
            </span>
          </FormItem>
        </Col>
      </Row>
      <template v-if="showGuardian">
        <div class="mb-3 mt-2 text-sm font-medium text-[hsl(var(--foreground))]">监护人信息</div>
        <Row :gutter="12">
          <Col :span="8">
            <FormItem label="监护人姓名" required>
              <Input v-model:value="form.guardian_name" />
            </FormItem>
          </Col>
          <Col :span="8">
            <FormItem label="监护人身份证" required>
              <Input v-model:value="form.guardian_id_card" maxlength="18" />
            </FormItem>
          </Col>
          <Col :span="8">
            <FormItem label="监护人手机" required>
              <Input v-model:value="form.guardian_mobile" maxlength="11" />
            </FormItem>
          </Col>
        </Row>
      </template>
      <!-- 健康信息：字段与交互对齐患者小程序；一行两列排布 -->
      <div class="mb-3 mt-2 text-sm font-medium text-[hsl(var(--foreground))]">健康信息</div>
      <Row :gutter="12">
        <Col :span="12">
          <FormItem label="肝功能">
            <RadioGroup v-model:value="form.liver_function" :options="LIVER_RENAL_OPTIONS" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="肾功能">
            <RadioGroup v-model:value="form.renal_function" :options="LIVER_RENAL_OPTIONS" />
          </FormItem>
        </Col>
        <Col
          v-for="block in historyBlocks"
          v-show="block.visible()"
          :key="block.key"
          :span="12"
        >
          <FormItem :label="block.label">
            <RadioGroup
              :value="Number(form[block.statusField])"
              :options="HISTORY_STATUS_OPTIONS"
              @update:value="(v: number) => onHistoryStatusChange(block.statusField, block.historyField, v)"
            />
            <Select
              v-if="Number(form[block.statusField]) === 1"
              class="mt-2 w-full"
              mode="tags"
              :value="getHistoryTags(block.historyField)"
              :options="block.options"
              placeholder="选择或输入后回车添加"
              allow-clear
              @update:value="(v: string[]) => setHistoryTags(block.historyField, v)"
            />
          </FormItem>
        </Col>
      </Row>
    </Form>
  </Modal>
</template>
