<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue';
import type { VxeFormInstance, VxeFormListeners, VxeFormProps } from 'vxe-pc-ui';
import { getDictionaryMethod } from '@/request/api/dictionary.api';
import { pageDiagnoseSymptomMethod, pageDiagnoseTypeMethod, pageMedicineMethod } from '@/request/api/care.api';
import { patientBasicInfoMethod, patientMethod } from '@/request/api/patient.api';
import { notification } from 'ant-design-vue';
import { message as Message } from 'ant-design-vue/es/components';
import RemoteSelect from '@/libs/v-select-page/RemoteSelect.vue';
import builtinRegions from '@/tools/regions';

interface FormModel {}
const props = defineProps<{
  data: any;
}>();
const emits = defineEmits<{
  destroy: [refresh?: boolean];
}>();

// 编辑患者
const form = ref({});
const initializing = ref(false);
const submitting = ref(false);
// 身份证校验（格式、生日、校验码）
function validateChinaId(id: string): boolean {
  const re = /^\d{17}[\dXx]$/;
  if (!re.test(id)) return false;
  const y = parseInt(id.substring(6, 10));
  const m = parseInt(id.substring(10, 12));
  const d = parseInt(id.substring(12, 14));
  const birth = new Date(y, m - 1, d);
  if (birth.getFullYear() !== y || birth.getMonth() + 1 !== m || birth.getDate() !== d || y < 1900 || y > new Date().getFullYear()) {
    return false;
  }
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
  let sum = 0;
  for (let i = 0; i < 17; i++) {
    sum += parseInt(id[i]) * weights[i];
  }
  const check = codes[sum % 11];
  return check === id[17].toUpperCase();
}

// 根据身份证号计算年龄和性别
function calculateAgeAndGender(cardno: string) {
  if (!cardno || cardno.length !== 18) return;

  try {
    if (!validateChinaId(cardno)) {
      // 身份证无效时不修改性别和年龄
      return;
    }
    // 提取出生年月日
    const year = parseInt(cardno.substring(6, 10));
    const month = parseInt(cardno.substring(10, 12));
    const day = parseInt(cardno.substring(12, 14));

    // 计算年龄
    const today = new Date();
    const birthDate = new Date(year, month - 1, day);
    let age = today.getFullYear() - birthDate.getFullYear();

    // 如果还没到生日，年龄减1
    if (today.getMonth() < month - 1 || (today.getMonth() === month - 1 && today.getDate() < day)) {
      age--;
    }

    // 提取性别（第17位数字，奇数为男，偶数为女）
    const genderCode = parseInt(cardno.substring(16, 17));
    const gender = genderCode % 2 === 1 ? '0' : '1'; // 0-男，1-女

    // 更新表单数据
    form.value.age = age;
    form.value.sex = gender;
  } catch (error) {
    console.error('身份证号解析失败:', error);
  }
}

// 监听身份证号变化
watch(
  () => form.value.cardno,
  (newCardno, oldCardno) => {
    if (initializing.value) return;
    if (newCardno && newCardno.length === 18 && validateChinaId(newCardno)) {
      calculateAgeAndGender(newCardno);
      return;
    }
    if (!newCardno) {
      const hasServerAge = form.value && (form.value as any).age != null && (form.value as any).age !== '';
      const hasServerSex = form.value && (form.value as any).sex != null && (form.value as any).sex !== '';
      if (!hasServerAge && !hasServerSex) {
        (form.value as any).age = '';
        (form.value as any).sex = '';
      }
    }
  }
);

function mapToCascader(list: any[], level: number = 1): any[] {
  return (list || []).map((i: any) => {
    const node: any = {
      label: i.name || i.label,
      value: i.code || i.value,
    };
    // 仅保留到“区/县”三级，截断更深层级（如街道）
    if (i.children && level < 3) {
      node.children = mapToCascader(i.children, level + 1);
    }
    return node;
  });
}

const regionOptions = ref<any[]>([]);
// 通过 code 查找省市区路径（返回 [省code, 市code, 区code]）
function findPathByCode(list: any[], targetCode: string, path: string[] = []): string[] | null {
  for (const node of list || []) {
    const code = String(node.value);
    const nextPath = [...path, code];
    if (code === String(targetCode)) return nextPath;
    if (node.children) {
      const found = findPathByCode(node.children, targetCode, nextPath);
      if (found) return found;
    }
  }
  return null;
}

// 通过 code 查找对应的名称
function findNameByCode(list: any[], targetCode: string): string | null {
  for (const node of list || []) {
    const code = String(node.value);
    if (code === String(targetCode)) {
      return node.label;
    }
    if (node.children) {
      const found = findNameByCode(node.children, targetCode);
      if (found) return found;
    }
  }
  return null;
}

// 规范化表单里的 region，使其为 [省code, 市code, 区code]
function normalizeRegionValue() {
  const fv: any = form.value as any;
  const raw: any = fv?.region ?? fv?.regionCode ?? fv?.districtCode ?? fv?.areaCode ?? fv?.cityCode ?? fv?.provinceCode;
  if (!raw) {
    const pc = fv?.provinceCode ?? fv?.province ?? fv?.province_id;
    const cc = fv?.cityCode ?? fv?.city ?? fv?.city_id;
    const dc = fv?.districtCode ?? fv?.district ?? fv?.areaCode ?? fv?.area ?? fv?.district_id;
    const arr = [pc, cc, dc].filter((v) => v != null).map((v) => String(v));
    if (arr.length) fv.region = arr;
    return;
  }

  // 已是数组：确保都是字符串
  if (Array.isArray(raw)) {
    fv.region = raw.map((v) => String(v));
    return;
  }

  // 对象格式：{ provinceCode, cityCode, districtCode }
  if (typeof raw === 'object') {
    const pc = raw.provinceCode ?? raw.province ?? raw.province_id;
    const cc = raw.cityCode ?? raw.city ?? raw.city_id;
    const dc = raw.districtCode ?? raw.district ?? raw.areaCode ?? raw.area ?? raw.district_id;
    const arr = [pc, cc, dc].filter((v) => v != null).map((v) => String(v));
    if (arr.length) fv.region = arr;
    return;
  }

  // 单个区/市/省的 code：尝试通过树找到完整路径
  const rawCode = String(raw);
  const path = findPathByCode(regionOptions.value, rawCode);
  if (path && path.length) {
    fv.region = path;
  }
}
// 获取女性特殊期
const womenSpecialPeriod = ref<{ id: string; name: string }[]>([]);
const womenSpecialPeriodLoading = ref(false);
// 获取女性特殊期
async function getWomenSpecialPeriod() {
  womenSpecialPeriodLoading.value = true;
  const res = await getDictionaryMethod('women_special_period');
  if (res && res.length > 0) {
    womenSpecialPeriod.value = res.map((item: any) => ({
      id: item.value,
      name: item.label,
    }));

    // 若表单里存的是名称，将其规范为编码（id）
    const current = (form.value as any)?.womenSpecialPeriod;
    if (current !== undefined && current !== null && current !== '') {
      const foundById = womenSpecialPeriod.value.find((i) => String(i.id) === String(current));
      const foundByName = womenSpecialPeriod.value.find((i) => i.name === current);
      if (!foundById && foundByName) (form.value as any).womenSpecialPeriod = foundByName.id;
    }
  }
  womenSpecialPeriodLoading.value = false;
}
// 获取食物过敏
const foodAllergy = ref<{ id: string; name: string }[]>([]);
const foodAllergyLoading = ref(false);
// 获取食物过敏
async function getFoodAllergy() {
  foodAllergyLoading.value = true;
  const res = await getDictionaryMethod('food_allergy');
  if (res && res.length > 0) {
    foodAllergy.value = res.map((item: any) => ({
      id: item.value,
      name: item.label,
    }));
    const raw = (form.value as any)?.foodAllergy;
    const currentArr: any[] = Array.isArray(raw) ? raw : typeof raw === 'string' ? raw.split(',') : raw != null ? [raw] : [];
    if (currentArr.length > 0) {
      const idList = currentArr
        .map((v: any) => {
          const strVal = String(v).trim();
          const byId = foodAllergy.value.find((i) => String(i.id) === strVal);
          const byName = foodAllergy.value.find((i) => i.name === strVal);
          return byId ? byId.id : byName ? byName.id : undefined;
        })
        .filter((v: any) => v !== undefined);
      if (idList.length > 0) (form.value as any).foodAllergy = idList;
    }
  }
}
// 获取喜好口味
const hobbyFlavor = ref<{ id: string; name: string }[]>([]);
const hobbyFlavorLoading = ref(false);
// 获取喜好口味
async function getHobbyFlavor() {
  hobbyFlavorLoading.value = true;
  const res = await getDictionaryMethod('hobby_flavor');
  if (res && res.length > 0) {
    hobbyFlavor.value = res.map((item: any) => ({
      id: item.value,
      name: item.label,
    }));
    const raw = (form.value as any)?.hobbyFlavor;
    const currentArr: any[] = Array.isArray(raw) ? raw : typeof raw === 'string' ? raw.split(',') : raw != null ? [raw] : [];
    if (currentArr.length > 0) {
      const idList = currentArr
        .map((v: any) => {
          const strVal = String(v).trim();
          const byId = hobbyFlavor.value.find((i) => String(i.id) === strVal);
          const byName = hobbyFlavor.value.find((i) => i.name === strVal);
          return byId ? byId.id : byName ? byName.id : undefined;
        })
        .filter((v: any) => v !== undefined);
    if (idList.length > 0) (form.value as any).hobbyFlavor = idList;
    }
  }
  hobbyFlavorLoading.value = false;
}
// 获取职业
const job = ref<{ id: string; name: string }[]>([]);
const jobLoading = ref(false);
// 获取职业
async function getJob() {
  jobLoading.value = true;
  const res = await getDictionaryMethod('job');
  if (res && res.length > 0) {
    job.value = res.map((item: any) => ({
      id: item.value,
      name: item.label,
    }));
    const current = (form.value as any)?.job;
    if (current !== undefined && current !== null && current !== '') {
      const byId = job.value.find((i) => String(i.id) === String(current));
      const byName = job.value.find((i) => i.name === current);
      if (!byId && byName) (form.value as any).job = byName.id;
    }
  }
  jobLoading.value = false;
}
// 获取性别
const genders = ref<{ id: string; name: string }[]>([]);
const gendersLoading = ref(false);
async function getGender() {
  gendersLoading.value = true;
  const res = await getDictionaryMethod('sys_user_sex');
  if (res && res.length > 0) {
    genders.value = res.map((item: any) => ({
      id: item.value || item.label,
      name: item.label,
    }));
  }
  gendersLoading.value = false;
}
// 身份证是否有效，用于锁定年龄/性别编辑
const isIdLocked = computed(() => {
  const id = (form.value as any)?.cardno;
  return !!id && id.length === 18 && validateChinaId(id);
});
// 是否女性
const isFemale = computed(() => {
  const val: any = form.value?.sex;
  return val === '女' || val === '1' || val === 1;
});
async function getPatientDetail() {
  try {
    const res: any = await patientMethod(props.data);
    if (res) {
      initializing.value = true;
      const normSex = res.sex != null ? String(res.sex) : res.sex;
      Object.assign(form.value as any, { ...res, sex: normSex });
    }
  } catch (error) {
    notification.error({ message: '获取数据失败' });
  } finally {
    initializing.value = false;
  }
}

onMounted(async () => {
  if (props.data) {
    await getPatientDetail();
  }
  // 获取女性特殊期
  await getWomenSpecialPeriod();
  // 获取食物过敏
  await getFoodAllergy();
  // 获取喜好口味
  await getHobbyFlavor();
  // 获取职业
  await getJob();
  // 获取性别
  await getGender();
  try {
    // 优先加载完整行政区数据（需已安装 china-division）
    const mod: any = await import('china-division/dist/pcas-code.json');
    regionOptions.value = Array.isArray(mod.default) ? mapToCascader(mod.default) : mapToCascader(mod);
  } catch (e) {
    // 回退到内置简化数据
    regionOptions.value = builtinRegions ?? [];
  }
  // 地区数据准备好后，根据 code 回填省市区
  normalizeRegionValue();
});
const formProps = reactive<VxeFormProps<FormModel>>({
  titleWidth: 100,
  titleAlign: 'right',
  titleColon: true,
  items: [
    { field: 'name', title: '姓名', span: 24, itemRender: { name: 'VxeInput' } },
    {
      field: 'cardno',
      title: '身份证号',
      span: 24,
      itemRender: { name: 'VxeInput', props: { minLength: 18, maxLength: 18 } },
    },
    { field: 'age', title: '年龄', span: 24, itemRender: { name: 'VxeNumberInput', props: { controls: false, disabled: computed(() => isIdLocked.value) } } },

    {
      field: 'sex',
      title: '性别',
      span: 24,
      itemRender: { name: 'template' },
      slots: { default: 'sex-radio' },
    },
    { field: 'height', title: '身高(cm)', span: 24, itemRender: { name: 'VxeNumberInput', props: { controls: false } } },
    { field: 'weight', title: '体重(kg)', span: 24, itemRender: { name: 'VxeNumberInput', props: { controls: false } } },
    {
      field: 'womenSpecialPeriod',
      title: '女性特殊期',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          placeholder: '请选择女性特殊期',
          clearable: true,
          options: computed(() =>
            womenSpecialPeriod.value.map((item) => ({
              label: item.name,
              value: item.id,
            }))
          ),
        },
      },
      visibleMethod: () => isFemale.value,
    },
    {
      field: 'foodAllergy',
      title: '食物过敏',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          multiple: true,
          placeholder: '请选择食物过敏',
          clearable: true,
          options: computed(() =>
            foodAllergy.value.map((item) => ({
              label: item.name,
              value: item.id,
            }))
          ),
        },
      },
    },
    {
      field: 'hobbyFlavor',
      title: '喜好口味',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          multiple: true,
          placeholder: '请选择喜好口味',
          clearable: true,
          options: computed(() =>
            hobbyFlavor.value.map((item) => ({
              label: item.name,
              value: item.id,
            }))
          ),
        },
      },
    },
    {
      field: 'drinkState',
      title: '饮酒情况',
      span: 24,
      itemRender: {
        name: 'VxeRadioGroup',
        options: [
          { label: '是', value: 'Y' },
          { label: '否', value: 'N' },
        ],
      },
    },
    {
      field: 'smokeState',
      title: '吸烟情况',
      span: 24,
      itemRender: {
        name: 'VxeRadioGroup',
        options: [
          { label: '是', value: 'Y' },
          { label: '否', value: 'N' },
        ],
      },
    },
    { field: 'region', title: '现住址', span: 24, itemRender: { name: 'template' }, slots: { default: 'region-cascader' } },
    { field: 'detailAddress', title: '详细住址', span: 24, itemRender: { name: 'VxeInput', props: { placeholder: '请输入详细住址', clearable: true } } },
    {
      field: 'job',
      title: '职业',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          placeholder: '请选择职业',
          options: computed(() =>
            job.value.map((item) => ({
              label: item.name,
              value: item.id,
            }))
          ),
        },
      },
    },
    { align: 'center', span: 24, slots: { default: 'active' } },
  ],
  rules: {
    // name: [{ required: true, message: '请输入姓名' }],
    age: [{ required: true, message: '请输入年龄' }],
    sex: [{ required: true, message: '请选择性别' }],
    height: [{ required: true, message: '请输入身高' }],
    weight: [{ required: true, message: '请输入体重' }],
  },
});
const formEmits: VxeFormListeners<FormModel> = {
  async submit({ data }) {
    // 提交前处理多选字段：将数组转换为字符串
    const processedData = { ...data };
    // 处理省市区数据：将数组转换为单独的字段
    if (Array.isArray(processedData.region) && processedData.region.length >= 3) {
      const [provinceCode, cityCode, areaCode] = processedData.region;

      // 获取对应的名称
      const provinceName = findNameByCode(regionOptions.value, provinceCode);
      const cityName = findNameByCode(regionOptions.value, cityCode);
      const areaName = findNameByCode(regionOptions.value, areaCode);

      // 设置省市区代码和名称
      processedData.provinceCode = provinceCode;
      processedData.provinceName = provinceName;
      processedData.cityCode = cityCode;
      processedData.cityName = cityName;
      processedData.areaCode = areaCode;
      processedData.areaName = areaName;

      console.log('省市区处理结果:', {
        provinceCode,
        provinceName,
        cityCode,
        cityName,
        areaCode,
        areaName,
      });
    }

    if (Array.isArray(processedData.foodAllergy)) {
      processedData.foodAllergy = processedData.foodAllergy.join(',');
    }
    if (Array.isArray(processedData.hobbyFlavor)) {
      processedData.hobbyFlavor = processedData.hobbyFlavor.join(',');
    }
    submitting.value = true;
    try {
      await patientBasicInfoMethod(processedData);
      Message.success(`患者基本信息修改成功`);
      emits('destroy', true);
    } catch (error) {
      console.error('提交失败:', error);
    } finally {
      submitting.value = false;
    }
  },
  reset() {
    // 重置表单数据
    Object.assign(form.value, props.data || {});
  },
};
</script>

<template>
  <vxe-form ref="formRef" :data="form" v-bind="formProps" v-on="formEmits">
    <template #active>
      <vxe-button type="submit" status="primary" content="提交" :loading="submitting"></vxe-button>
      <vxe-button type="reset" content="重置" :disabled="submitting"></vxe-button>
    </template>
    <template #sex-radio="{ data, field }">
      <div class="lock-wrapper">
        <vxe-radio-group
          v-model="data[field]"
          :options="genders.map(i => ({ label: i.name, value: i.id }))"
        />
        <div
          v-if="isIdLocked"
          class="lock-mask"
          @mousedown.capture.prevent.stop
          @mouseup.capture.prevent.stop
          @click.capture.prevent.stop
          @touchstart.capture.prevent.stop
          @touchend.capture.prevent.stop
          @keydown.capture.prevent.stop
        />
      </div>
    </template>
    <template #region-cascader="{ data, field }">
      <a-cascader
        v-model:value="data[field]"
        :options="regionOptions"
        :field-names="{ value: 'value', label: 'label', children: 'children' }"
        placeholder="请选择"
        allow-clear
        show-search
        style="width: 100%"
      />
    </template>
    <template #disease-remote-select="{ data, field }">
      <RemoteSelect
        v-model:value="data[field]"
        :load="pageMedicineMethod"
        :multiple="true"
        key-prop="name"
        @blur="formRef?.validateField(field)"
        @update:value="formRef?.validateField(field)"
      />
    </template>
    <template #symptom-remote-select="{ data, field }">
      <RemoteSelect
        v-model:value="data[field]"
        :load="pageDiagnoseTypeMethod"
        :multiple="true"
        key-prop="name"
        @blur="formRef?.validateField(field)"
        @update:value="formRef?.validateField(field)"
      />
    </template>
    <template #syndrome-remote-select="{ data, field }">
      <RemoteSelect
        v-model:value="data[field]"
        :load="pageDiagnoseSymptomMethod"
        :multiple="true"
        key-prop="name"
        @blur="formRef?.validateField(field)"
        @update:value="formRef?.validateField(field)"
      />
    </template>
  </vxe-form>
</template>

<style scoped lang="scss">
:deep(.lock-wrapper) {
  position: relative;
}
:deep(.lock-mask) {
  position: absolute;
  inset: 0;
  background: transparent;
  pointer-events: auto;
}
</style>
