<template>
  <el-dialog v-model="dialogVisible" title="学生列表排序" width="500px" :closeOnClickModal="false">
    <div id="student-sort-container" class="student-sort-container">
      <el-scrollbar max-height="400px" viewStyle="position: relative;overflow-x: hidden;">
        <slick-list v-model:list="sortedStudents" lockAxis="y" tag="div" axis="y" class="slick-list">
          <slick-item v-for="(item, index) in sortedStudents" :key="item.shortId" :index="index" tag="div" class="student-item">
            <span class="drag-handle">☰</span>
            <span class="student-index">{{ index + 1 }}</span>
            <span class="student-name">{{ item.studentName }}</span>
            <span class="student-id">ID: {{ item.shortId }}</span>
          </slick-item>
        </slick-list>
      </el-scrollbar>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="saveAndClose">保存排序</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
  import { ElMessage } from 'element-plus';
  import { ref, watch } from 'vue';
  import { SlickItem, SlickList } from 'vue-slicksort';
  import { saveStudentOrderAxios } from '@/api/meeting';

  export interface StudentInfo {
    /** 学生长 ID */
    longId: number;
    /** 学生姓名 */
    studentName: string;
    /** 学生短 ID */
    shortId: number;
  }

  const props = defineProps<{
    /** 是否显示弹窗 */
    modelValue: boolean;
    /** 房间 ID */
    roomId: string;
    /** 学生列表 */
    students: StudentInfo[];
  }>();

  const emit = defineEmits<{
    'update:modelValue': [value: boolean];
  }>();

  /** 本地排序后的学生列表 */
  const sortedStudents = ref<StudentInfo[]>([...props.students]);

  /** 控制弹窗显示 */
  const dialogVisible = ref(props.modelValue);

  /**
   * 监听弹窗开启，初始化排序
   */
  watch(
    () => props.modelValue,
    (newVal) => {
      dialogVisible.value = newVal;
      if (newVal) {
        // 弹窗打开时，复制一份学生列表用于排序
        sortedStudents.value = [...props.students];
      }
    },
    { immediate: true }
  );

  /**
   * 监听弹窗关闭状态
   */
  watch(dialogVisible, (newVal) => {
    emit('update:modelValue', newVal);
  });

  /**
   * 保存排序并关闭弹窗
   */
  async function saveAndClose() {
    try {
      const studentLongIds = sortedStudents.value.map((s) => s.longId);

      const result = await saveStudentOrderAxios(props.roomId, studentLongIds);

      if (result.data) {
        ElMessage.success('排序已保存');
        dialogVisible.value = false;
      } else {
        throw new Error('保存失败');
      }
    } catch (error) {
      console.error('[学生排序] 保存失败:', error);
      ElMessage.error('保存失败，请重试');
    }
  }

  /**
   * 取消并关闭弹窗
   */
  function cancel() {
    dialogVisible.value = false;
  }
</script>

<style scoped lang="scss">
  .student-sort-container {
    padding: 10px 0;
    position: relative;
  }

  .slick-list {
    width: 100%;
  }

  .student-item {
    z-index: 999999;
    display: flex;
    align-items: center;
    padding: 12px 16px;
    margin-bottom: 8px;
    background: #f5f7fa;
    border-radius: 8px;
    cursor: move;
    border: 2px solid transparent;
    user-select: none;

    .drag-handle {
      font-size: 20px;
      color: #909399;
      margin-right: 12px;
      cursor: grab;
    }

    .student-index {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      background: #409eff;
      color: #fff;
      border-radius: 50%;
      font-weight: bold;
      margin-right: 12px;
      font-size: 14px;
    }

    .student-name {
      flex: 1;
      font-size: 14px;
      color: #303133;
    }

    .student-id {
      font-size: 12px;
      color: #909399;
    }
  }

  .dialog-footer {
    display: flex;
    justify-content: center;
    gap: 16px;
  }
</style>
