<template>
  <el-dialog
      :model-value="visible"
      title="移动笔记到"
      width="400px"
      @close="handleClose"
      :close-on-click-modal="false"
      :destroy-on-close="true"
  >
    <div v-if="noteToMove" class="move-note-info">
      <el-icon class="note-icon"><Document /></el-icon>
      <span class="note-title" :title="noteToMove.title">{{ noteToMove.title }}</span>
      <el-tag v-if="currentGroupName" type="info" size="small" effect="plain">{{ currentGroupName }}</el-tag>
    </div>
    
    <div class="select-wrapper">
      <el-select-v2
          v-model="moveToGroupId"
          :options="flattenOptions"
          placeholder="请选择目标分类"
          clearable
          filterable
          :height="200"
          style="width: 100%;"
      >
        <template #default="{ item }">
          <div class="select-option" :class="{ 'is-current': item.value === noteToMove?.groupingId }">
            <span class="indent" :style="{ width: item.indent + 'px' }"></span>
            <el-icon class="option-icon">
              <Folder v-if="item.hasChildren" />
              <Document v-else />
            </el-icon>
            <span class="option-label">{{ item.label }}</span>
            <el-tag v-if="item.value === noteToMove?.groupingId" type="warning" size="small">当前</el-tag>
          </div>
        </template>
      </el-select-v2>
    </div>
    
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button 
          type="primary" 
          @click="handleSubmit" 
          :disabled="!moveToGroupId || moveToGroupId === noteToMove?.groupingId"
          :loading="isLoading"
      >
        确定
      </el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, watch, computed } from 'vue';
import { ElMessage } from 'element-plus';
import { Folder, Document } from '@element-plus/icons-vue';
import { updateMarkdown } from '@/api/CommonApi.js';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  categoryOptions: {
    type: Array,
    default: () => [],
  },
  noteToMove: {
    type: Object,
    default: null,
  }
});

const emit = defineEmits(['update:visible', 'move-success']);

const moveToGroupId = ref(null);
const isLoading = ref(false);

// 扁平化选项，用于虚拟选择器
const flattenOptions = computed(() => {
  const result = [];
  const flatten = (options, depth = 0) => {
    for (const option of options) {
      result.push({
        value: option.id,
        label: option.grouping,
        indent: depth * 20,
        hasChildren: option.children && option.children.length > 0
      });
      if (option.children && option.children.length > 0) {
        flatten(option.children, depth + 1);
      }
    }
  };
  flatten(props.categoryOptions);
  return result;
});

// 使用 Map 缓存分类名称，O(1) 查找
const groupNameMap = computed(() => {
  const map = new Map();
  const traverse = (options) => {
    for (const option of options) {
      map.set(option.id, option.grouping);
      if (option.children && option.children.length > 0) {
        traverse(option.children);
      }
    }
  };
  traverse(props.categoryOptions);
  return map;
});

// 计算当前分类名称
const currentGroupName = computed(() => {
  if (!props.noteToMove?.groupingId) return '';
  return groupNameMap.value.get(props.noteToMove.groupingId) || '';
});

watch(() => props.visible, (newVal) => {
  if (!newVal) {
    moveToGroupId.value = null;
    isLoading.value = false;
  }
});

const handleClose = () => {
  emit('update:visible', false);
};

const handleSubmit = async () => {
  if (!moveToGroupId.value) {
    ElMessage.error('请选择目标分类');
    return;
  }
  if (!props.noteToMove) {
    ElMessage.error('没有需要移动的笔记');
    return;
  }
  if (moveToGroupId.value === props.noteToMove.groupingId) {
    ElMessage.warning('不能移动到当前分类');
    return;
  }

  isLoading.value = true;
  try {
    const payload = {
      ...props.noteToMove,
      groupingId: moveToGroupId.value,
    };
    await updateMarkdown(payload);
    ElMessage.success('笔记移动成功');
    emit('move-success');
    handleClose();
  } catch (error) {
    // 错误已在 axios 拦截器中显示，这里不再重复显示
    console.error('移动失败:', error);
  } finally {
    isLoading.value = false;
  }
};
</script>

<style scoped>
.move-note-info {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  padding: 10px 14px;
  background-color: #f5f7fa;
  border-radius: 6px;
  border-left: 3px solid #409eff;
}

.note-icon {
  color: #409eff;
  font-size: 18px;
  flex-shrink: 0;
}

.note-title {
  flex: 1;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
}

.select-wrapper {
  width: 100%;
}

.select-option {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
}

.select-option.is-current {
  color: #e6a23c;
}

.indent {
  display: inline-block;
  flex-shrink: 0;
}

.option-icon {
  color: #409eff;
  font-size: 16px;
  flex-shrink: 0;
}

.option-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
