<template>
  <!-- 添加/编辑菜单对话框 -->
  <el-dialog
    :model-value="visible"
    :title="dialogTitle"
    width="500px"
    :close-on-click-modal="false"
    @update:model-value="handleDialogClose"
  >
    <el-form
      :model="currentMenu"
      label-width="100px"
      :rules="formRules"
      ref="menuFormRef"
    >
      <el-form-item label="父级菜单" prop="pid">
        <el-tree-select
          v-model="currentMenu.pid"
          :data="parentMenuOptions"
          :props="{ value: 'id', label: 'title', children: 'children' }"
          placeholder="请选择父级菜单"
          clearable
          check-strictly
          :render-after-expand="false"
          style="width: 100%"
          @change="handleParentChange"
        />
      </el-form-item>

      <el-form-item label="菜单名称" prop="title">
        <el-input v-model="currentMenu.title" placeholder="请输入菜单名称" />
      </el-form-item>

      <el-form-item label="菜单类型" prop="type">
        <el-radio-group v-model="currentMenu.type" style="width: 100%">
          <el-radio-button :value="1">目录</el-radio-button>
          <el-radio-button :value="2">页面</el-radio-button>
          <el-radio-button :value="3">外链</el-radio-button>
          <el-radio-button :value="4">单页</el-radio-button>
        </el-radio-group>
        <div
          style="
            margin-top: 8px;
            font-size: 12px;
            color: var(--el-text-color-secondary);
          "
        >
          <div>
            • 目录：只有路由地址，用于<span
              style="color: var(--el-color-primary)"
              >目录管理</span
            >和<span style="color: var(--el-color-primary)">菜单分组</span>
          </div>
          <div>
            • 页面：有路由和组件地址，用于<span
              style="color: var(--el-color-primary)"
              >页面管理</span
            >
          </div>
          <div>
            • 外链：无路由和组件，用于<span
              style="color: var(--el-color-primary)"
              >外链管理</span
            >和<span style="color: var(--el-color-primary)">权限控制</span>
          </div>
          <div>
            • 单页：根据路由从单页表获取内容显示，无需填写组件路径
          </div>
        </div>
      </el-form-item>

      <el-form-item label="路由地址" prop="path" v-if="currentMenu.type !== 3">
        <el-input v-model="currentMenu.path" placeholder="例如：/system" />
        <div v-if="currentMenu.type === 4" style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary);">
          单页类型：路由需与单页管理中的路由一致，系统会自动从单页表获取内容
        </div>
      </el-form-item>

      <el-form-item
        label="组件路径"
        prop="component_path"
        v-if="currentMenu.type === 2"
      >
        <el-input
          v-model="currentMenu.component_path"
          placeholder="例如：/apps/knowledge/index.vue"
        />
      </el-form-item>

      <el-form-item
        label="外链地址"
        prop="link_url"
        v-if="currentMenu.type === 3"
      >
        <el-input
          v-model="currentMenu.link_url"
          required
          placeholder="例如：https://www.baidu.com"
        />
      </el-form-item>

      <el-form-item label="菜单图片" prop="image">
        <el-upload
          class="image-uploader"
          :action="uploadUrl"
          :headers="uploadHeaders"
          :show-file-list="false"
          :on-success="handleImageSuccess"
          :on-error="handleImageError"
          :before-upload="beforeImageUpload"
          accept="image/*"
        >
          <img v-if="currentMenu.image" :src="getImageUrl(currentMenu.image)" class="image-preview" />
          <div v-else class="upload-placeholder">
            <el-icon class="image-uploader-icon"><Plus /></el-icon>
            <div class="el-upload__text">点击上传图片</div>
          </div>
        </el-upload>
        <div style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary);">
          建议尺寸：400x300，支持 jpg、png、gif 格式，大小不超过 2MB
        </div>
        <el-button 
          v-if="currentMenu.image" 
          size="small" 
          type="danger" 
          text
          @click="handleRemoveImage"
          style="margin-top: 8px;"
        >
          删除图片
        </el-button>
      </el-form-item>

      <el-form-item label="描述" prop="desc">
        <el-input
          v-model="currentMenu.desc"
          type="textarea"
          :rows="3"
          placeholder="例如：系统管理"
        />
      </el-form-item>

      <el-form-item label="排序" prop="sort">
        <el-input-number
          v-model="currentMenu.sort"
          :min="0"
          placeholder="数字越小越靠前"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSave">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { ElMessage, ElForm } from "element-plus";
import { Plus } from "@element-plus/icons-vue";

// 定义菜单数据类型
interface Menu {
  id: number;
  pid: number;
  title: string;
  type: number;
  path: string;
  component_path: string;
  link_url?: string;
  image?: string;
  sort: number;
  desc: string;
  children?: Menu[];
  hasChildren?: boolean;
}

// Props
interface Props {
  visible: boolean;
  menu: Partial<Menu> | null;
  parentMenuOptions: Menu[];
  dialogType: "add" | "edit" | "addSub";
  parentTitle?: string;
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  menu: null,
  parentMenuOptions: () => [],
  dialogType: "add",
  parentTitle: "",
});

// Emits
const emit = defineEmits<{
  (e: "update:visible", value: boolean): void;
  (e: "save", menu: Partial<Menu>): void;
  (e: "cancel"): void;
}>();

// 表单引用
const menuFormRef = ref<InstanceType<typeof ElForm>>();

// 当前操作的菜单
const currentMenu = ref<Partial<Menu>>({
  id: 0,
  pid: 0,
  title: "",
  type: 1,
  path: "",
  component_path: "",
  image: "",
  sort: 0,
  desc: "",
});

// 上传配置
// @ts-ignore
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
const uploadUrl = ref(API_BASE_URL + '/admin/uploadfiles');
const uploadHeaders = ref({
  'Authorization': 'Bearer ' + (localStorage.getItem('token') || '')
});

// 查找父级菜单路径的递归函数
const findMenuPath = (menuList: Menu[], targetId: number): string => {
  for (const menu of menuList) {
    if (menu.id === targetId) {
      return menu.path || "";
    }
    if (menu.children && menu.children.length > 0) {
      const childPath = findMenuPath(menu.children, targetId);
      if (childPath) return childPath;
    }
  }
  return "";
};

// 处理父级菜单变化 - 自动填充父级路径到路由地址
const handleParentChange = (value: number) => {
  if (value === 0) {
    // 选择顶级菜单，清空路径
    currentMenu.value.path = "";
  } else {
    // 选择子菜单，自动填充父级路径
    const parentPath = findMenuPath(props.parentMenuOptions, value);
    if (parentPath) {
      currentMenu.value.path = parentPath;
    }
  }
};

// 监听props变化，更新当前菜单
watch(
  () => props.menu,
  (newMenu) => {
    if (newMenu) {
      currentMenu.value = {
        ...newMenu,
        // 确保 pid 有默认值
        pid: newMenu.pid ?? 0,
      };
    } else {
      // 重置表单
      currentMenu.value = {
        id: 0,
        pid: 0,
        title: "",
        path: "",
        component_path: "",
        sort: 0,
        desc: "",
        type: 1,
      };
    }
  },
  { immediate: true }
);

// 监听props.visible变化
watch(
  () => props.visible,
  (newVisible) => {
    if (newVisible && props.dialogType === "add") {
      // 新增时重置表单
      currentMenu.value = {
        id: 0,
        pid: 0,
        title: "",
        path: "",
        component_path: "",
        image: "",
        sort: 0,
        desc: "",
        type: 1,
      };
    }
  }
);

// 对话框标题
const dialogTitle = computed(() => {
  switch (props.dialogType) {
    case "add":
      return "添加菜单";
    case "edit":
      return "编辑菜单";
    case "addSub":
      return `添加子菜单 (父菜单: ${props.parentTitle || "顶级菜单"})`;
    default:
      return "操作菜单";
  }
});

// 表单验证规则
const formRules = ref({
  title: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  path: [
    {
      required: true,
      validator: (rule: any, value: any, callback: any) => {
        if (currentMenu.value.type === 3) {
          // 外链类型不需要路径
          callback();
        } else if (!value || value.trim() === "") {
          callback(new Error("请输入路由地址"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  component_path: [
    {
      required: true,
      validator: (rule: any, value: any, callback: any) => {
        if (currentMenu.value.type === 2) {
          // 页面类型需要组件路径
          if (!value || value.trim() === "") {
            callback(new Error("请输入组件路径"));
          } else {
            callback();
          }
        } else {
          // 其他类型（目录、外链、单页）不需要组件路径
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  sort: [{ required: true, message: "请输入排序号", trigger: "blur" }],
});


// 监听菜单类型变化，自动清空不相关的字段
watch(
  () => currentMenu.value.type,
  (newType, oldType) => {
    if (newType === oldType) return; // 避免初始化时的触发

    if (newType === 1) {
      // 目录：清空组件路径，保留路径
      currentMenu.value.component_path = "";
    } else if (newType === 2) {
      // 页面：保留路径和组件路径
      // 不清空，保持现有值
    } else if (newType === 3) {
      // 外链：清空路径和组件路径
      currentMenu.value.path = "";
      currentMenu.value.component_path = "";
    } else if (newType === 4) {
      // 单页：清空组件路径，保留路径（路径用于匹配单页表）
      currentMenu.value.component_path = "";
    }
  }
);

// 取消操作
const handleCancel = () => {
  emit("update:visible", false);
  emit("cancel");
};

// 处理对话框关闭
const handleDialogClose = (value: boolean) => {
  if (!value) {
    emit("update:visible", false);
    emit("cancel");
  }
};

// 图片上传前校验
const beforeImageUpload = (file: any) => {
  const isImage = file.type.startsWith('image/');
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    return false;
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!');
    return false;
  }
  return true;
};

// 图片上传成功
const handleImageSuccess = (response: any) => {
  if (response.code === 200) {
    // 直接保存相对路径，不拼接API_BASE_URL
    currentMenu.value.image = response.data.url || response.data.path;
    ElMessage.success('图片上传成功');
  } else {
    ElMessage.error(response.msg || '图片上传失败');
  }
};

// 图片上传失败
const handleImageError = () => {
  ElMessage.error('图片上传失败，请重试');
};

// 删除图片
const handleRemoveImage = () => {
  currentMenu.value.image = '';
  ElMessage.success('图片已删除');
};

// 获取图片完整URL（用于预览）
const getImageUrl = (imagePath: string) => {
  if (!imagePath) return '';
  // 如果是绝对路径，直接返回
  if (imagePath.startsWith('http')) return imagePath;
  // 如果是相对路径，拼接API基础地址
  return API_BASE_URL + imagePath;
};

// 保存菜单
const handleSave = async () => {
  // 表单验证
  if (!menuFormRef.value) return;
  const valid = await menuFormRef.value.validate();
  if (!valid) return;

  // 解决后端时间字段问题：过滤掉不需要的字段
  const payload = { ...currentMenu.value };

  // 触发保存事件
  emit("save", payload);
};
</script>

<style lang="less" scoped>
/* 对话框样式精简 */
:deep(.el-dialog__body) {
  padding: 20px;
  max-height: 60vh;
  overflow-y: auto;
}

:deep(.el-form-item) {
  margin-bottom: 16px;
}

/* 图片上传样式 */
.image-uploader {
  :deep(.el-upload) {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);

    &:hover {
      border-color: var(--el-color-primary);
    }
  }
}

.image-preview {
  width: 178px;
  height: 178px;
  display: block;
  object-fit: cover;
}

.upload-placeholder {
  width: 178px;
  height: 178px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--el-text-color-secondary);
  
  .image-uploader-icon {
    font-size: 28px;
    margin-bottom: 8px;
  }
  
  .el-upload__text {
    font-size: 14px;
  }
}
</style>
