<template>
  <div class="container-box">
    <div class="header-bar">
      <h2>菜单管理</h2>
      <div class="header-actions">
        <el-button @click="expandAll">
          <el-icon>
            <FolderOpened />
          </el-icon>
          全部展开
        </el-button>
        <el-button @click="collapseAll">
          <el-icon>
            <Folder />
          </el-icon>
          全部折叠
        </el-button>
        <el-button type="primary" @click="handleAddMenu">
          <el-icon>
            <Plus />
          </el-icon>
          添加菜单
        </el-button>
        <el-button @click="refresh" :loading="loading">
          <el-icon>
            <Refresh />
          </el-icon>
          刷新
        </el-button>
      </div>
    </div>

    <el-divider></el-divider>

    <!-- 树形表格 -->
    <el-table
      ref="tableRef"
      :data="menuTree"
      style="width: 100%"
      row-key="id"
      border
      v-loading="loading"
      element-loading-text="正在加载..."
      :tree-props="{
        children: 'children',
        hasChildren: 'hasChildren',
      }"
      @row-click="handleRowClick"
    >
      <el-table-column prop="title" label="菜单名称" width="200">
        <template #default="scope">
          <div class="menu-item">
            <i
              v-if="scope.row.icon"
              :class="scope.row.icon"
              class="menu-icon"
            ></i>
            <span>{{ scope.row.title }}</span>
          </div>
        </template>
      </el-table-column>

      <el-table-column
        prop="id"
        width="60"
        label="ID"
        align="center"
      ></el-table-column>

      <el-table-column prop="path" label="路由地址"></el-table-column>

      <el-table-column
        prop="MenuType"
        label="菜单类型"
        width="120"
        align="center"
      >
        <template #default="scope">
          <el-tag :type="getMenuTypeTagType(scope.row.type)">
            {{ getMenuTypeTitle(scope.row.type) }}
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column
        prop="sort"
        label="排序"
        width="80"
        align="center"
      ></el-table-column>

      <el-table-column prop="is_visible" label="是否显示" width="100" align="center">
        <template #default="scope">
          <el-tag :type="scope.row.is_visible === 1 ? 'success' : 'danger'">{{ scope.row.is_visible === 1 ? '显示' : '隐藏' }}</el-tag>
        </template>
      </el-table-column>

      <el-table-column prop="views" label="菜单显示" width="180" align="center">
        <template #default="scope">
          <el-tag v-if="Array.isArray(scope.row.views) && scope.row.views.includes(1)" type="primary" style="margin-right:6px;">
            平台端
          </el-tag>
          <el-tag v-if="Array.isArray(scope.row.views) && scope.row.views.includes(2)" type="warning">
            租户端
          </el-tag>
          <el-tag v-if="!Array.isArray(scope.row.views) || scope.row.views.length === 0" type="info">
            未设置
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column prop="status" label="状态" width="100" align="center">
        <template #default="scope">
          <el-switch
            v-model="scope.row.status"
            :active-value="1"
            :inactive-value="0"
            @change="handleStatusChange(scope.row)"
            @click.stop
            :disabled="!scope.row.id"
          />
        </template>
      </el-table-column>

      <el-table-column label="操作" width="280" fixed="right" align="center">
        <template #default="scope">
          <el-button
            size="small"
            text
            @click.stop="handleAddSubMenu(scope.row)"
            :disabled="scope.row.type === 3"
          >
            <el-icon>
              <CirclePlus />
            </el-icon>
            <span>子菜单</span>
          </el-button>

          <el-button size="small" text @click.stop="handleEditMenu(scope.row)">
            <el-icon>
              <Edit />
            </el-icon>
            <span>编辑</span>
          </el-button>

          <el-button
            size="small"
            text
            type="danger"
            @click.stop="handleDeleteMenu(scope.row)"
          >
            <el-icon>
              <Delete />
            </el-icon>
            <span>删除</span>
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 引入编辑组件 -->
    <MenuEdit
      v-model:visible="dialogVisible"
      :menu="dialogMenu"
      :parent-menu-options="parentMenuOptions"
      :dialog-type="dialogType"
      :parent-title="dialogParentTitle"
      @save="handleMenuSave"
      @cancel="handleMenuCancel"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { ElMessage, ElMessageBox, ElForm } from "element-plus";
import {
  Plus,
  CirclePlus,
  Edit,
  Delete,
  Refresh,
  FolderOpened,
  Folder,
} from "@element-plus/icons-vue";
import {
  getAllMenus,
  updateMenuStatus,
  createMenu,
  updateMenu,
  deleteMenu,
} from "@/api/menu";
import MenuEdit from "./components/edit.vue";

// 定义菜单数据类型
interface Menu {
  id: number;
  pid: number;
  title: string;
  path: string;
  component_path: string;
  icon: string;
  sort: number;
  status: 0 | 1;
  is_visible?: 0 | 1;
  views?: number[];
  type: 1 | 2 | 3; // 1:目录 2:页面 3:接口
  permission: string;
  children?: Menu[];
  hasChildren?: boolean;
}

// 菜单树形数据
const menuTree = ref<Menu[]>([]);
const loading = ref(false);

// 表格引用
const tableRef = ref<any>(null);

// 对话框相关变量
const dialogVisible = ref(false);
const dialogMenu = ref<Partial<Menu> | null>(null);
const dialogType = ref<"add" | "edit" | "addSub">("add");
const dialogParentTitle = ref("");

// 父级菜单选项
const parentMenuOptions = ref<Menu[]>([]);

let fetchMenusPromise: Promise<any> | null = null;

// 菜单树递归排序：按 sort 升序，sort 相同按 id 升序
function sortMenuTree(menus: Menu[]): Menu[] {
  return menus
    .map((item) => ({
      ...item,
      children: item.children ? sortMenuTree(item.children) : [],
    }))
    .sort((a, b) => {
      const sortA = Number(a.sort ?? 999999);
      const sortB = Number(b.sort ?? 999999);
      if (sortA === sortB) {
        return Number(a.id ?? 0) - Number(b.id ?? 0);
      }
      return sortA - sortB;
    });
}

const fetchMenus = async () => {
  if (fetchMenusPromise) {
    return fetchMenusPromise;
  }

  loading.value = true;

  fetchMenusPromise = (async () => {
    try {
      const result = await getAllMenus();
      if (result.code === 200) {
        const sortedMenus = sortMenuTree(result.data || []);
        menuTree.value = sortedMenus;
        parentMenuOptions.value = [
          {
            id: 0,
            pid: 0,
            title: "顶级菜单",
            children: [],
          } as Menu,
          ...sortedMenus,
        ];
      } else {
        ElMessage.error("获取菜单失败: " + result.message);
      }
    } catch (error) {
      ElMessage.error("获取菜单数据失败: " + (error as Error).message);
    } finally {
      loading.value = false;
      fetchMenusPromise = null;
    }
  })();

  return fetchMenusPromise;
};

// 刷新界面
async function refresh() {
  loading.value = true;
  try {
    await fetchMenus();
    ElMessage.success("刷新成功");
  } catch (error) {
    ElMessage.error("刷新失败");
  } finally {
    loading.value = false;
  }
}

// 获取所有菜单行数据（包括子节点）
function getAllMenuRows(menuList: Menu[]): Menu[] {
  const rows: Menu[] = [];
  menuList.forEach((menu) => {
    rows.push(menu);
    if (menu.children && menu.children.length > 0) {
      rows.push(...getAllMenuRows(menu.children));
    }
  });
  return rows;
}

// 全部展开
function expandAll() {
  if (!tableRef.value) return;
  const allRows = getAllMenuRows(menuTree.value);
  allRows.forEach((row) => {
    if (row.children && row.children.length > 0) {
      tableRef.value.toggleRowExpansion(row, true);
    }
  });
}

// 全部折叠
function collapseAll() {
  if (!tableRef.value) return;
  const allRows = getAllMenuRows(menuTree.value);
  allRows.forEach((row) => {
    if (row.children && row.children.length > 0) {
      tableRef.value.toggleRowExpansion(row, false);
    }
  });
}

// 处理行点击事件 - 展开/折叠树形结构
const handleRowClick = (row: Menu) => {
  if (!tableRef.value) return;

  // 检查该行是否有子节点
  const hasChildren = row.children && row.children.length > 0;

  if (hasChildren) {
    // 切换展开/折叠状态（toggleRowExpansion 会自动切换当前状态）
    tableRef.value.toggleRowExpansion(row);
  }
};

// 构建菜单树（处理父子关系）
const buildMenuTree = (menuList: Menu[]): Menu[] => {
  return menuList;
};

// 获取菜单类型名称
const getMenuTypeTitle = (type: number) => {
  const typeMap = { 1: "目录", 2: "页面", 3: "接口" };
  return typeMap[type as keyof typeof typeMap] || "未知类型";
};

// 获取菜单类型标签样式
const getMenuTypeTagType = (type: number) => {
  const typeMap = { 1: "primary", 2: "success", 3: "info" };
  return typeMap[type as keyof typeof typeMap] || "default";
};

// 处理状态变更
const handleStatusChange = async (menu: Menu) => {
  try {
    const result = await updateMenuStatus(menu.id, menu.status);
    if (!result.success) {
      ElMessage.error(result.message);
      // 状态更新失败时回滚
      menu.status = menu.status === 1 ? 0 : 1;
    }
  } catch (error) {
    ElMessage.error("更新状态失败: " + (error as Error).message);
    menu.status = menu.status === 1 ? 0 : 1;
  }
};

// 添加子菜单
const handleAddSubMenu = (parentMenu: Menu) => {
  dialogType.value = "addSub";
  dialogParentTitle.value = parentMenu.title;
  dialogMenu.value = {
    id: 0,
    pid: parentMenu.id,
    title: "",
    path: "",
    component_path: "",
    icon: "",
    sort: 0,
    status: 1,
    is_visible: 1,
    is_platform: 1,
    type: parentMenu.type === 2 ? 1 : parentMenu.type,
    permission: "",
  };
  dialogVisible.value = true;
};

// 编辑菜单
const handleEditMenu = (menu: Menu) => {
  dialogType.value = "edit";
  dialogMenu.value = { ...menu };
  dialogVisible.value = true;
};

// 删除菜单
const handleDeleteMenu = (menu: Menu) => {
  ElMessageBox.confirm(
    `确定要删除菜单 "${menu.title}" 吗？${menu.hasChildren ? "其下所有子菜单也将被删除。" : ""}`,
    "确认删除",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    },
  ).then(async () => {
    try {
      const result = await deleteMenu(menu.id);
      if (result.success) {
        ElMessage.success("删除成功");
        fetchMenus();
      } else {
        ElMessage.error("删除失败: " + result.message);
      }
    } catch (error) {
      ElMessage.error("删除失败: " + (error as Error).message);
    }
  });
};

// 添加菜单
const handleAddMenu = () => {
  dialogType.value = "add";
  dialogMenu.value = null;
  dialogVisible.value = true;
};

// 处理菜单保存
const handleMenuSave = async (menu: Partial<Menu>) => {
  try {
    // 解决后端时间字段问题：过滤掉不需要的字段
    const payload = { ...menu };

    // 确保 pid 是整数类型（后端要求必须是整数）
    // 处理数组情况：如果 pid 是数组（el-cascader 返回的是路径数组），取最后一个元素
    let pidValue: any = payload.pid;
    if (Array.isArray(pidValue)) {
      pidValue = pidValue.length > 0 ? pidValue[pidValue.length - 1] : null;
    }

    // 强制转换为整数
    if (pidValue === null || pidValue === undefined || pidValue === "") {
      payload.pid = 0;
    } else {
      const parsedPid = parseInt(String(pidValue), 10);
      if (isNaN(parsedPid)) {
        payload.pid = 0;
      } else {
        payload.pid = parsedPid;
      }
    }

    // 最终验证：确保 payload.pid 是数字类型，不是数组
    if (Array.isArray(payload.pid)) {
      payload.pid =
        Array.isArray(payload.pid) && payload.pid.length > 0
          ? parseInt(String(payload.pid[payload.pid.length - 1]), 10) || 0
          : 0;
    }

    // 确保是数字类型
    if (typeof payload.pid !== "number") {
      payload.pid = parseInt(String(payload.pid), 10) || 0;
    }

    if (menu.id === 0) {
      // 新增菜单
      const result = await createMenu(payload as Menu);
      if (result.code === 200) {
        // 修改这里，检查 code 而不是 success
        ElMessage.success(result.msg || "菜单添加成功");
        dialogVisible.value = false;
        await fetchMenus();
      } else {
        ElMessage.error(result.msg || "添加失败");
      }
    } else {
      // 编辑菜单
      const result = await updateMenu(menu.id!, payload as Menu);
      if (result.code === 200) {
        // 修改这里，检查 code 而不是 success
        ElMessage.success(result.msg || "更新成功");
        dialogVisible.value = false;
        await fetchMenus();
      } else {
        ElMessage.error(result.msg || "更新失败");
      }
    }
  } catch (error) {
    ElMessage.error("操作失败: " + (error as Error).message);
  }
};

// 处理菜单取消
const handleMenuCancel = () => {
  dialogVisible.value = false;
};

// 组件挂载时加载菜单
onMounted(() => {
  fetchMenus();
});
</script>

<style lang="less" scoped>
.header-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
}

.header-bar h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
}

.header-actions {
  display: flex;
  gap: 8px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #f2f3f5;
}

.card-header span {
  font-size: 18px;
  font-weight: 500;
}

/* 表格核心样式 */
:deep(.el-table) {
  border-radius: 0;
  width: 100% !important;
}

:deep(.el-table__body td) {
  padding: 12px 0;
  vertical-align: middle;
}

/* 展开图标与菜单内容对齐 */
:deep(.el-table__expand-icon) {
  margin: 0 !important;
  vertical-align: middle;
}

:deep(.el-table__expand-icon-cell) {
  padding: 0 8px !important;
}

/* 菜单项样式 */
.menu-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  vertical-align: middle;
}

.menu-icon {
  font-size: 16px;
  width: 20px;
  text-align: center;
}

/* 隐藏无子女菜单的展开图标 */
:deep(.el-table__expand-icon--hidden) {
  visibility: hidden;
  width: 24px;
}

:deep(.el-table__expand-icon) {
  margin-right: 8px !important;
  vertical-align: middle;
}

/* 对话框样式精简 */
:deep(.el-dialog__body) {
  padding: 20px;
  max-height: 60vh;
  overflow-y: auto;
}

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