<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import dayjs from 'dayjs';
import { fetchCreateOrgLeaderRelation, fetchUpdateOrgLeaderRelation } from '@/service/api';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import BusinessFormSection from '@/components/custom/business-form-section.vue';
import { $t } from '@/locales';

defineOptions({ name: 'UserOrgLeaderOperateDialog' });

interface Props {
  operateType: UI.TableOperateType;
  rowData?: Api.SystemManage.OrgLeaderRelation | null;
  dept?: Api.SystemManage.Dept | null;
  candidateUsers: Api.SystemManage.OrgLeaderCandidateUser[];
}

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 } = useFormRules();

const submitting = ref(false);
const isEdit = computed(() => props.operateType === 'edit');

const title = computed(() => {
  const titleMap: Record<UI.TableOperateType, string> = {
    add: $t('page.system.user.addLeader'),
    edit: $t('page.system.user.editLeader')
  };

  return titleMap[props.operateType];
});

type Model = {
  userId: string | null;
  effectiveFrom: Date | null;
  effectiveUntil: Date | null;
  remark: string;
};

const model = ref<Model>(createDefaultModel());

const candidateOptions = computed(() => {
  const options = [...props.candidateUsers];
  const rowData = props.rowData;

  if (isEdit.value && rowData && !options.some(item => item.id === rowData.userId)) {
    options.unshift({
      id: rowData.userId,
      nickname: rowData.userNickname,
      deptId: rowData.deptId,
      deptName: props.dept?.name ?? null
    });
  }

  return options;
});

const rules = {
  userId: createRequiredRule($t('page.system.user.form.candidateUser'))
} satisfies Partial<Record<keyof Model, App.Global.FormRule>>;

function createCurrentTime() {
  return dayjs().second(0).millisecond(0).toDate();
}

function createDefaultModel(): Model {
  return {
    userId: null,
    effectiveFrom: createCurrentTime(),
    effectiveUntil: null,
    remark: ''
  };
}

function initModel() {
  model.value = createDefaultModel();

  if (isEdit.value && props.rowData) {
    model.value = {
      userId: props.rowData.userId,
      effectiveFrom: props.rowData.effectiveFrom ? dayjs(props.rowData.effectiveFrom).toDate() : createCurrentTime(),
      effectiveUntil: props.rowData.effectiveUntil ? dayjs(props.rowData.effectiveUntil).toDate() : null,
      remark: props.rowData.remark ?? ''
    };
  }
}

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

async function handleSubmit() {
  if (!props.dept?.id) {
    return;
  }

  await validate();

  const effectiveFrom = model.value.effectiveFrom ? dayjs(model.value.effectiveFrom).valueOf() : null;
  const effectiveUntil = model.value.effectiveUntil ? dayjs(model.value.effectiveUntil).valueOf() : null;

  if (effectiveFrom && effectiveUntil && effectiveFrom > effectiveUntil) {
    window.$message?.warning($t('common.pleaseCheckValue'));
    return;
  }

  const payload: Api.SystemManage.SaveOrgLeaderRelationParams = {
    deptId: props.dept.id,
    userId: model.value.userId,
    effectiveFrom,
    effectiveUntil,
    remark: model.value.remark.trim() || null
  };

  submitting.value = true;

  const request =
    isEdit.value && props.rowData
      ? await fetchUpdateOrgLeaderRelation({ id: props.rowData.id, ...payload })
      : await fetchCreateOrgLeaderRelation(payload);

  const { error } = request;

  submitting.value = false;

  if (error) {
    return;
  }

  window.$message?.success($t(isEdit.value ? 'common.updateSuccess' : 'common.addSuccess'));
  closeDialog();
  emit('submitted');
}

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

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

<template>
  <BusinessFormDialog
    v-model="visible"
    :title="title"
    preset="sm"
    :confirm-loading="submitting"
    :scrollbar="false"
    @confirm="handleSubmit"
  >
    <ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
      <BusinessFormSection :title="$t('page.system.user.sections.basicInfo')">
        <ElRow :gutter="16">
          <ElCol :span="24">
            <ElFormItem :label="$t('page.system.user.deptName')">
              <ElInput :model-value="dept?.name || $t('common.noData')" disabled />
            </ElFormItem>
          </ElCol>
          <ElCol :span="24">
            <ElFormItem :label="$t('page.system.user.candidateUser')" prop="userId">
              <ElSelect
                v-model="model.userId"
                class="w-full"
                filterable
                :placeholder="$t('page.system.user.form.candidateUser')"
              >
                <ElOption v-for="item in candidateOptions" :key="item.id" :label="item.nickname" :value="item.id" />
              </ElSelect>
            </ElFormItem>
          </ElCol>
          <ElCol :span="24">
            <ElFormItem :label="$t('page.system.user.effectiveFrom')" prop="effectiveFrom" style="width: 100%">
              <ElDatePicker
                v-model="model.effectiveFrom"
                class="w-full"
                style="width: 100%"
                type="datetime"
                clearable
                :placeholder="$t('page.system.user.form.effectiveFrom')"
              />
            </ElFormItem>
          </ElCol>
          <ElCol :span="24">
            <ElFormItem :label="$t('page.system.user.effectiveUntil')" prop="effectiveUntil" style="width: 100%">
              <ElDatePicker
                v-model="model.effectiveUntil"
                class="w-full"
                style="width: 100%"
                type="datetime"
                clearable
                :placeholder="$t('page.system.user.form.effectiveUntil')"
              />
            </ElFormItem>
          </ElCol>
          <ElCol :span="24">
            <ElFormItem :label="$t('page.system.user.relationRemark')" prop="remark">
              <ElInput
                v-model="model.remark"
                type="textarea"
                :rows="4"
                :placeholder="$t('page.system.user.form.relationRemark')"
              />
            </ElFormItem>
          </ElCol>
        </ElRow>
      </BusinessFormSection>
    </ElForm>
  </BusinessFormDialog>
</template>
