<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { userGenderOptions } from '@/constants/business';
import { fetchUpdateMyProfile } from '@/service/api';
import { useForm, useFormRules } from '@/hooks/common/form';
import { translateOptions } from '@/utils/common';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import { buildProfileUpdatePayload } from './profile-model';

defineOptions({ name: 'ProfileInfoDialog' });

interface Props {
  profile?: Api.Auth.MyProfileDetail | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { formRef, validate } = useForm();
const { createRequiredRule, patternRules } = useFormRules();

const submitting = ref(false);

const genderOptions = computed(() =>
  translateOptions(userGenderOptions).map(item => ({
    ...item,
    value: Number(item.value) as Api.SystemManage.UserGender
  }))
);

const model = ref<Api.Auth.UpdateMyProfileParams>({
  nickname: '',
  email: '',
  mobile: '',
  sex: 1,
  avatar: ''
});

const rules = computed<Record<string, App.Global.FormRule[]>>(() => ({
  nickname: [createRequiredRule('请输入昵称')],
  mobile: model.value.mobile?.trim() ? [patternRules.phone] : [],
  email: model.value.email?.trim() ? [patternRules.email] : []
}));

function initModel() {
  model.value = {
    nickname: props.profile?.nickname ?? '',
    email: props.profile?.email ?? '',
    mobile: props.profile?.mobile ?? '',
    sex: props.profile?.sex ?? 1,
    avatar: props.profile?.avatar ?? ''
  };
}

function closeDialog() {
  visible.value = false;
}

async function handleSubmit() {
  if (!props.profile) {
    return;
  }

  await validate();

  submitting.value = true;

  const { error } = await fetchUpdateMyProfile(buildProfileUpdatePayload(model.value));

  submitting.value = false;

  if (error) {
    return;
  }

  window.$message?.success('个人信息更新成功');
  closeDialog();
  emit('submitted');
}

watch(visible, async value => {
  if (!value) {
    return;
  }

  initModel();
  await nextTick();
  formRef.value?.clearValidate();
});
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    title="编辑基本信息"
    preset="sm"
    :confirm-loading="submitting"
    @confirm="handleSubmit"
  >
    <ElForm ref="formRef" :model="model" :rules="rules" label-position="top" autocomplete="off">
      <ElRow :gutter="16">
        <ElCol :span="24">
          <ElFormItem label="昵称" prop="nickname">
            <ElInput v-model="model.nickname" maxlength="30" placeholder="请输入昵称" />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="手机号" prop="mobile">
            <ElInput v-model="model.mobile" maxlength="20" placeholder="请输入手机号" />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="邮箱" prop="email">
            <ElInput v-model="model.email" maxlength="100" placeholder="请输入邮箱" />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="性别" prop="sex">
            <ElSelect v-model="model.sex" placeholder="请选择性别">
              <ElOption v-for="{ label, value } in genderOptions" :key="value" :label="label" :value="value" />
            </ElSelect>
          </ElFormItem>
        </ElCol>
      </ElRow>
    </ElForm>
  </BusinessFormDialog>
</template>
