<template>
  <el-dialog
    v-model="visible"
    title="批量新增用户"
    width="500px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    top="10vh"
    append-to-body
    @close="handleClose"
    @open="modalBeforeOpen"
  >
    <el-form
      ref="formRef"
      :model="formModel"
      :rules="rules"
      label-width="120px"
    >
      <el-form-item label="考试名称">
        <el-input :value="curExamName" disabled />
      </el-form-item>
      <el-form-item label="角色" prop="role">
        <el-select v-model="formModel.role" placeholder="请选择角色">
          <el-option label="学校管理员" value="school_admin" />
          <el-option label="扫描员" value="scanner" />
          <el-option label="普通用户" value="user" />
          <el-option label="科组长" value="subject_leader" />
          <el-option label="复核员" value="reviewer" />
          <el-option label="评卷员" value="marker" />
        </el-select>
      </el-form-item>
      <el-form-item label="命名规则" prop="namingRule">
        <el-input v-model="formModel.namingRule" placeholder="自定义前缀">
          <template #append>+科目代码+流水号</template>
        </el-input>
      </el-form-item>
      <el-form-item label="每分组账号数" prop="accountsPerGroup">
        <el-input-number
          v-model="formModel.accountsPerGroup"
          :min="1"
          :max="20"
          :step="1"
          :precision="0"
          :controls="false"
          step-strictly
        />
      </el-form-item>
      <el-form-item label="随机密码" prop="randomPassword">
        <el-switch
          v-model="formModel.randomPassword"
          @change="randomPasswordChange"
        />
      </el-form-item>
      <el-form-item
        v-if="!formModel.randomPassword"
        label="密码"
        prop="password"
      >
        <el-input
          v-model="formModel.password"
          type="password"
          placeholder="请输入密码"
          :disabled="formModel.randomPassword"
          show-password
        />
      </el-form-item>
      <el-form-item label="选择科目" prop="subjectIds">
        <el-button type="primary" @click="openSelectSubjectDialog"
          >设置</el-button
        >
        <div v-if="selectedSubjects.length > 0" style="margin-left: 10px">
          已选择 {{ selectedSubjects.length }} 个科目
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSave"
          >确定</el-button
        >
      </span>
    </template>
  </el-dialog>

  <SelectSubjectDialog
    ref="selectSubjectDialogRef"
    :select-ids="formModel.subjectIds"
    @selected="handleSubjectsSelected"
  />
</template>

<script setup lang="ts">
  import { ref, reactive, computed } from 'vue';
  import type { FormInstance } from 'element-plus';
  import { FormRules } from '@/types/global';
  import { ElMessage } from 'element-plus';
  import { useAppStore } from '@/store';
  import useLoading from '@/hooks/loading';
  import useModal from '@/hooks/modal';

  import type { SubjectItem } from '@/api/types/base';
  import type { BatchCreateUserParam } from '@/api/types/user';
  import { batchAddUser } from '@/api/user';

  import SelectSubjectDialog from './SelectSubjectDialog.vue';

  defineOptions({
    name: 'BatchCreateUserDialog',
  });

  /* modal */
  const { visible, open, close } = useModal();
  defineExpose({ open, close });

  const emit = defineEmits(['modified']);

  const appStore = useAppStore();
  const curExamName = computed(() => appStore.curExam?.name || '');

  const formRef = ref<FormInstance>();

  const rules: FormRules<keyof BatchCreateUserParam> = {
    role: [{ required: true, message: '请选择角色', trigger: 'change' }],
    namingRule: [
      { required: true, message: '请输入命名规则', trigger: 'change' },
    ],
    accountsPerGroup: [
      { required: true, message: '请输入每分组账号数', trigger: 'change' },
    ],
    password: [
      {
        required: true,
        message: '请输入密码或选择随机密码',
        trigger: 'change',
      },
    ],
    subjectIds: [
      {
        required: true,
        validator: (rule: any, value: number[], callback: any) => {
          if (!value || value.length === 0) {
            callback(new Error('请选择科目'));
          } else {
            callback();
          }
        },
        trigger: 'change',
      },
    ],
  };

  function getInitialFormModel(): BatchCreateUserParam {
    return {
      examId: appStore.curExam?.id || 0,
      role: '',
      namingRule: '',
      accountsPerGroup: 1,
      randomPassword: false,
      password: '',
      subjectIds: [],
    };
  }

  const formModel = reactive<BatchCreateUserParam>(getInitialFormModel());
  const selectedSubjects = ref<SubjectItem[]>([]);
  const selectSubjectDialogRef = ref<InstanceType<
    typeof SelectSubjectDialog
  > | null>(null);

  function randomPasswordChange() {
    if (formModel.randomPassword) {
      formModel.password = '';
    }
  }

  const handleClose = () => {
    formRef.value?.resetFields();
  };

  const openSelectSubjectDialog = () => {
    selectSubjectDialogRef.value?.open(selectedSubjects.value.map((s) => s.id));
  };

  const handleSubjectsSelected = (subjects: SubjectItem[]) => {
    selectedSubjects.value = subjects;
    formModel.subjectIds = subjects.map((s) => s.id);
    ElMessage.success(`已选择 ${subjects.length} 个科目`);
    formRef.value?.validateField('subjectIds');
  };

  const { loading, setLoading } = useLoading();
  const handleSave = async () => {
    if (!formRef.value) return;

    const valid = await formRef.value.validate().catch(() => false);
    if (!valid) return;

    try {
      setLoading(true);
      let res = true;
      await batchAddUser({ ...formModel }).catch(() => {
        res = false;
      });
      setLoading(false);
      if (!res) return;
      ElMessage.success(`批量新增用户成功！`);
      emit('modified');
      close();
    } catch (error) {
      console.error('API request error:', error);
      ElMessage.error('操作失败，请重试');
    }
  };

  const modalBeforeOpen = () => {
    Object.assign(formModel, getInitialFormModel());
    selectedSubjects.value = [];
  };
</script>
