<template>
  <Page>
    <div class="p-4">
      <!-- 搜索表单 -->
      <el-card class="mb-4">
        <el-form :model="searchForm" inline>
        <el-form-item label="菜单名称">
          <el-input
            v-model="searchForm.keyword"
            placeholder="请输入菜单名称"
            clearable
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
            <el-option label="显示" :value="1" />
            <el-option label="隐藏" :value="0" />
          </el-select>
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-select v-model="searchForm.type" placeholder="请选择类型" clearable>
            <el-option label="目录" value="catalog" />
            <el-option label="菜单" value="menu" />
            <el-option label="按钮" value="button" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">
            <Icon icon="ep:search" class="mr-1" />
            搜索
          </el-button>
          <el-button @click="handleReset">
            <Icon icon="ep:refresh" class="mr-1" />
            重置
          </el-button>
        </el-form-item>
        </el-form>
      </el-card>

      <!-- 操作按钮 -->
      <el-card class="mb-4">
        <div class="action-buttons">
      <el-button type="primary" @click="handleAdd">
        <Icon icon="ep:plus" class="mr-1" />
        新增菜单
      </el-button>
      <el-button type="success" @click="handleExpandAll">
        <Icon icon="ep:d-arrow-right" class="mr-1" />
        展开全部
      </el-button>
      <el-button type="info" @click="handleCollapseAll">
        <Icon icon="ep:d-arrow-left" class="mr-1" />
        收起全部
      </el-button>
    </div>

    <!-- 数据表格 -->
    <el-table
      v-loading="loading"
      :data="tableData"
      row-key="menuId"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      :default-expand-all="false"
      ref="tableRef"
    >
      <el-table-column prop="title" label="菜单名称" min-width="200">
        <template #default="{ row }">
          <div class="menu-title">
            <Icon :icon="row.icon || 'ep:folder'" class="mr-2" />
            <span>{{ row.title }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="type" label="类型" width="80">
        <template #default="{ row }">
          <el-tag :type="getTypeTagType(row.type)">
            {{ getTypeText(row.type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="path" label="路由路径" min-width="150" show-overflow-tooltip />
      <el-table-column prop="component" label="组件路径" min-width="150" show-overflow-tooltip />
      <el-table-column prop="permission" label="权限标识" min-width="150" show-overflow-tooltip />
      <el-table-column prop="sort" label="排序" width="80" />
      <el-table-column prop="status" label="状态" width="80">
        <template #default="{ row }">
          <el-tag :type="row.status === 1 ? 'success' : 'danger'">
            {{ row.status === 1 ? '显示' : '隐藏' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" width="180">
        <template #default="{ row }">
          {{ formatTime(row.createTime) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" size="small" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-button type="success" size="small" @click="handleAddChild(row)">
            新增子菜单
          </el-button>
          <el-button
            type="danger"
            size="small"
            @click="handleDelete(row)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="800px"
      @close="handleDialogClose"
    >
      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        label-width="120px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="上级菜单" prop="parentId">
              <el-tree-select
                v-model="formData.parentId"
                :data="menuTreeData"
                :props="treeSelectProps"
                placeholder="请选择上级菜单"
                check-strictly
                :render-after-expand="false"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单类型" prop="type">
              <el-radio-group v-model="formData.type" @change="handleTypeChange">
                <el-radio label="catalog">目录</el-radio>
                <el-radio label="menu">菜单</el-radio>
                <el-radio label="button">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="title">
              <el-input v-model="formData.title" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单图标" prop="icon">
              <el-input v-model="formData.icon" placeholder="请输入图标名称">
                <template #prepend>
                  <Icon :icon="formData.icon || 'ep:folder'" />
                </template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20" v-if="formData.type !== 'button'">
          <el-col :span="12">
            <el-form-item label="路由路径" prop="path">
              <el-input v-model="formData.path" placeholder="请输入路由路径" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="formData.type === 'menu'">
            <el-form-item label="组件路径" prop="component">
              <el-input v-model="formData.component" placeholder="请输入组件路径" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="权限标识" prop="permission">
              <el-input v-model="formData.permission" placeholder="请输入权限标识" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="排序" prop="sort">
              <el-input-number v-model="formData.sort" :min="0" style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20" v-if="formData.type !== 'button'">
          <el-col :span="12">
            <el-form-item label="是否隐藏" prop="hidden">
              <el-radio-group v-model="formData.hidden">
                <el-radio :label="0">显示</el-radio>
                <el-radio :label="1">隐藏</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否缓存" prop="keepAlive">
              <el-radio-group v-model="formData.keepAlive">
                <el-radio :label="1">缓存</el-radio>
                <el-radio :label="0">不缓存</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="状态" prop="status">
              <el-radio-group v-model="formData.status">
                <el-radio :label="1">启用</el-radio>
                <el-radio :label="0">禁用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="formData.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
          确定
        </el-button>
      </template>
    </el-dialog>
    </div>
  </Page>
</template>

<script lang="ts" setup>
// 1. Vue 相关导入
import { ref, reactive, onMounted, computed, type FormInstance } from 'vue';

// 2. Element Plus 组件导入
import {
  ElButton,
  ElCard,
  ElCol,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElTable,
  ElTableColumn,
  ElTag,
  ElTreeSelect,
  type ElTable,
} from 'element-plus';

// 3. 图标组件导入
import { Icon } from '@iconify/vue';

// 4. Vben 组件导入
import { Page } from '@vben/common-ui';

// 5. 项目内部导入
import {
  getMenuListApi,
  getMenuTreeApi,
  createMenuApi,
  updateMenuApi,
  deleteMenuApi,
  type Menu,
  type CreateMenuParams,
  type UpdateMenuParams,
  type MenuTreeNode,
} from '#/api/common/rbac';

// 响应式数据
const loading = ref(false);
const submitLoading = ref(false);
const tableData = ref<Menu[]>([]);
const menuTreeData = ref<MenuTreeNode[]>([]);
const currentParent = ref<Menu | null>(null);

// 搜索表单
const searchForm = reactive({
  keyword: '',
  status: undefined as number | undefined,
  type: undefined as string | undefined,
});

// 对话框
const dialogVisible = ref(false);
const isEdit = ref(false);
const isAddChild = ref(false);
const formRef = ref<FormInstance>();
const tableRef = ref<InstanceType<typeof ElTable>>();

// 表单数据
const formData = reactive<CreateMenuParams & { menuId?: number }>({
  parentId: 0,
  title: '',
  type: 'menu',
  path: '',
  component: '',
  icon: '',
  permission: '',
  sort: 0,
  hidden: 0,
  keepAlive: 1,
  status: 1,
  remark: '',
});

// 树形选择器配置
const treeSelectProps = {
  value: 'menuId',
  label: 'title',
  children: 'children',
};

// 表单验证规则
const formRules = {
  title: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' },
    { min: 2, max: 50, message: '菜单名称长度在 2 到 50 个字符', trigger: 'blur' },
  ],
  type: [
    { required: true, message: '请选择菜单类型', trigger: 'change' },
  ],
  path: [
    {
      validator: (rule: any, value: string, callback: any) => {
        if (formData.type !== 'button' && !value) {
          callback(new Error('请输入路由路径'));
        } else {
          callback();
        }
      },
      trigger: 'blur',
    },
  ],
  component: [
    {
      validator: (rule: any, value: string, callback: any) => {
        if (formData.type === 'menu' && !value) {
          callback(new Error('请输入组件路径'));
        } else {
          callback();
        }
      },
      trigger: 'blur',
    },
  ],
  permission: [
    { required: true, message: '请输入权限标识', trigger: 'blur' },
  ],
};

// 计算属性
const dialogTitle = computed(() => {
  if (isAddChild.value) {
    return `新增子菜单 - ${currentParent.value?.title}`;
  }
  return isEdit.value ? '编辑菜单' : '新增菜单';
});

// 方法
const formatTime = (timestamp: number) => {
  if (!timestamp) return '-';
  return new Date(timestamp * 1000).toLocaleString();
};

const getTypeText = (type: string) => {
  const map = {
    catalog: '目录',
    menu: '菜单',
    button: '按钮',
  };
  return map[type as keyof typeof map] || type;
};

const getTypeTagType = (type: string) => {
  const map = {
    catalog: 'warning',
    menu: 'primary',
    button: 'success',
  };
  return map[type as keyof typeof map] || 'info';
};

const loadData = async () => {
  loading.value = true;
  try {
    const params = {
      keyword: searchForm.keyword || undefined,
      status: searchForm.status,
      type: searchForm.type,
    };
    const result = await getMenuListApi(params);
    tableData.value = result;
  } catch (error) {
    ElMessage.error('加载数据失败');
  } finally {
    loading.value = false;
  }
};

const loadMenuTree = async () => {
  try {
    const result = await getMenuTreeApi();
    // 添加根节点
    menuTreeData.value = [
      {
        menuId: 0,
        title: '根目录',
        children: result,
      },
    ];
  } catch (error) {
    ElMessage.error('加载菜单树失败');
  }
};

const handleSearch = () => {
  loadData();
};

const handleReset = () => {
  searchForm.keyword = '';
  searchForm.status = undefined;
  searchForm.type = undefined;
  handleSearch();
};

const handleExpandAll = () => {
  const table = tableRef.value;
  if (table) {
    const expandAll = (data: Menu[]) => {
      data.forEach(row => {
        table.toggleRowExpansion(row, true);
        if (row.children) {
          expandAll(row.children);
        }
      });
    };
    expandAll(tableData.value);
  }
};

const handleCollapseAll = () => {
  const table = tableRef.value;
  if (table) {
    const collapseAll = (data: Menu[]) => {
      data.forEach(row => {
        table.toggleRowExpansion(row, false);
        if (row.children) {
          collapseAll(row.children);
        }
      });
    };
    collapseAll(tableData.value);
  }
};

const handleAdd = async () => {
  isEdit.value = false;
  isAddChild.value = false;
  currentParent.value = null;
  await loadMenuTree();
  resetForm();
  dialogVisible.value = true;
};

const handleAddChild = async (row: Menu) => {
  isEdit.value = false;
  isAddChild.value = true;
  currentParent.value = row;
  await loadMenuTree();
  resetForm();
  formData.parentId = row.menuId;
  dialogVisible.value = true;
};

const handleEdit = async (row: Menu) => {
  isEdit.value = true;
  isAddChild.value = false;
  currentParent.value = null;
  await loadMenuTree();
  Object.assign(formData, {
    menuId: row.menuId,
    parentId: row.parentId,
    title: row.title,
    type: row.type,
    path: row.path,
    component: row.component,
    icon: row.icon,
    permission: row.permission,
    sort: row.sort,
    hidden: row.hidden,
    keepAlive: row.keepAlive,
    status: row.status,
    remark: row.remark,
  });
  dialogVisible.value = true;
};

const handleDelete = async (row: Menu) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除菜单 "${row.title}" 吗？删除后子菜单也会被删除！`,
      '确认删除',
      {
        type: 'warning',
      }
    );
    await deleteMenuApi(row.menuId);
    ElMessage.success('删除成功');
    loadData();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败');
    }
  }
};

const handleTypeChange = (type: string) => {
  // 根据类型清空相关字段
  if (type === 'button') {
    formData.path = '';
    formData.component = '';
    formData.hidden = 0;
    formData.keepAlive = 0;
  } else if (type === 'catalog') {
    formData.component = '';
  }
};

const handleSubmit = async () => {
  if (!formRef.value) return;
  
  try {
    await formRef.value.validate();
    submitLoading.value = true;
    
    if (isEdit.value) {
      const updateData: UpdateMenuParams = {
        menuId: formData.menuId!,
        parentId: formData.parentId,
        title: formData.title,
        type: formData.type,
        path: formData.path,
        component: formData.component,
        icon: formData.icon,
        permission: formData.permission,
        sort: formData.sort,
        hidden: formData.hidden,
        keepAlive: formData.keepAlive,
        status: formData.status,
        remark: formData.remark,
      };
      await updateMenuApi(updateData);
      ElMessage.success('更新成功');
    } else {
      const createData: CreateMenuParams = {
        parentId: formData.parentId,
        title: formData.title,
        type: formData.type,
        path: formData.path,
        component: formData.component,
        icon: formData.icon,
        permission: formData.permission,
        sort: formData.sort,
        hidden: formData.hidden,
        keepAlive: formData.keepAlive,
        status: formData.status,
        remark: formData.remark,
      };
      await createMenuApi(createData);
      ElMessage.success('创建成功');
    }
    
    dialogVisible.value = false;
    loadData();
  } catch (error) {
    ElMessage.error(isEdit.value ? '更新失败' : '创建失败');
  } finally {
    submitLoading.value = false;
  }
};

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

const resetForm = () => {
  Object.assign(formData, {
    menuId: undefined,
    parentId: 0,
    title: '',
    type: 'menu',
    path: '',
    component: '',
    icon: '',
    permission: '',
    sort: 0,
    hidden: 0,
    keepAlive: 1,
    status: 1,
    remark: '',
  });
};

// 生命周期
onMounted(() => {
  loadData();
});
</script>

<style scoped>
.menu-page {
  padding: 20px;
}

.search-form {
  background: #fff;
  padding: 20px;
  border-radius: 4px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.action-buttons {
  background: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.menu-title {
  display: flex;
  align-items: center;
}
</style>