<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.type" placeholder="请选择类型" clearable>
            <el-option label="菜单" value="menu" />
            <el-option label="按钮" value="button" />
            <el-option label="接口" value="api" />
          </el-select>
        </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>
          <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="danger"
        :disabled="!selectedRows.length"
        @click="handleBatchDelete"
      >
        <Icon icon="ep:delete" class="mr-1" />
        批量删除
      </el-button>
      <el-button type="success" @click="handleSyncFromMenu">
        <Icon icon="ep:refresh" class="mr-1" />
        从菜单同步
      </el-button>
    </div>

    <!-- 数据表格 -->
    <el-table
      v-loading="loading"
      :data="tableData"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="permissionId" label="ID" width="80" />
      <el-table-column prop="name" label="权限名称" min-width="150" />
      <el-table-column prop="code" label="权限标识" min-width="200" show-overflow-tooltip />
      <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="resource" label="资源路径" min-width="200" show-overflow-tooltip />
      <el-table-column prop="method" label="请求方法" width="100">
        <template #default="{ row }">
          <el-tag v-if="row.method" :type="getMethodTagType(row.method)" size="small">
            {{ row.method }}
          </el-tag>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column prop="menuId" label="关联菜单" width="100">
        <template #default="{ row }">
          <el-tag v-if="row.menuId" type="info" size="small">
            {{ getMenuName(row.menuId) }}
          </el-tag>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <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="150" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" size="small" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-button
            type="danger"
            size="small"
            @click="handleDelete(row)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-wrapper">
      <el-pagination
        v-model:current-page="pagination.page"
        v-model:page-size="pagination.limit"
        :total="pagination.total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="700px"
      @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="name">
              <el-input v-model="formData.name" placeholder="请输入权限名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限标识" prop="code">
              <el-input v-model="formData.code" placeholder="请输入权限标识" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="权限类型" prop="type">
              <el-select v-model="formData.type" placeholder="请选择类型" @change="handleTypeChange">
                <el-option label="菜单" value="menu" />
                <el-option label="按钮" value="button" />
                <el-option label="接口" value="api" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="关联菜单" prop="menuId">
              <el-select v-model="formData.menuId" placeholder="请选择菜单" clearable filterable>
                <el-option
                  v-for="menu in menuOptions"
                  :key="menu.menuId"
                  :label="menu.title"
                  :value="menu.menuId"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="资源路径" prop="resource">
              <el-input v-model="formData.resource" placeholder="请输入资源路径" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="formData.type === 'api'">
            <el-form-item label="请求方法" prop="method">
              <el-select v-model="formData.method" placeholder="请选择请求方法">
                <el-option label="GET" value="GET" />
                <el-option label="POST" value="POST" />
                <el-option label="PUT" value="PUT" />
                <el-option label="DELETE" value="DELETE" />
                <el-option label="PATCH" value="PATCH" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <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-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="description">
          <el-input
            v-model="formData.description"
            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,
  ElPagination,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';

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

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

// 5. 项目内部导入
import {
  getPermissionListApi,
  createPermissionApi,
  updatePermissionApi,
  deletePermissionApi,
  batchDeletePermissionApi,
  syncPermissionFromMenuApi,
  type Permission,
  type CreatePermissionParams,
  type UpdatePermissionParams,
} from '#/api/rbac';
import { getMenuListApi, type Menu } from '#/api/rbac';

// 响应式数据
const loading = ref(false);
const submitLoading = ref(false);
const tableData = ref<Permission[]>([]);
const selectedRows = ref<Permission[]>([]);
const menuOptions = ref<Menu[]>([]);

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

// 分页
const pagination = reactive({
  page: 1,
  limit: 20,
  total: 0,
});

// 对话框
const dialogVisible = ref(false);
const isEdit = ref(false);
const formRef = ref<FormInstance>();

// 表单数据
const formData = reactive<CreatePermissionParams & { permissionId?: number }>({
  name: '',
  code: '',
  type: 'button',
  resource: '',
  method: '',
  menuId: undefined,
  sort: 0,
  status: 1,
  description: '',
});

// 表单验证规则
const formRules = {
  name: [
    { required: true, message: '请输入权限名称', trigger: 'blur' },
    { min: 2, max: 50, message: '权限名称长度在 2 到 50 个字符', trigger: 'blur' },
  ],
  code: [
    { required: true, message: '请输入权限标识', trigger: 'blur' },
    { min: 2, max: 100, message: '权限标识长度在 2 到 100 个字符', trigger: 'blur' },
    { pattern: /^[a-zA-Z][a-zA-Z0-9_:.-]*$/, message: '权限标识格式不正确', trigger: 'blur' },
  ],
  type: [
    { required: true, message: '请选择权限类型', trigger: 'change' },
  ],
  resource: [
    { max: 200, message: '资源路径不能超过 200 个字符', trigger: 'blur' },
  ],
  method: [
    {
      validator: (rule: any, value: string, callback: any) => {
        if (formData.type === 'api' && !value) {
          callback(new Error('接口类型权限必须选择请求方法'));
        } else {
          callback();
        }
      },
      trigger: 'change',
    },
  ],
  description: [
    { max: 500, message: '描述不能超过 500 个字符', trigger: 'blur' },
  ],
};

// 计算属性
const dialogTitle = computed(() => (isEdit.value ? '编辑权限' : '新增权限'));

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

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

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

const getMethodTagType = (method: string) => {
  const map = {
    GET: 'primary',
    POST: 'success',
    PUT: 'warning',
    DELETE: 'danger',
    PATCH: 'info',
  };
  return map[method as keyof typeof map] || 'info';
};

const getMenuName = (menuId: number) => {
  const menu = menuOptions.value.find(m => m.menuId === menuId);
  return menu ? menu.title : `菜单${menuId}`;
};

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

const loadMenuOptions = async () => {
  try {
    const result = await getMenuListApi({});
    // 扁平化菜单树
    const flattenMenu = (menus: Menu[]): Menu[] => {
      let result: Menu[] = [];
      menus.forEach(menu => {
        result.push(menu);
        if (menu.children) {
          result = result.concat(flattenMenu(menu.children));
        }
      });
      return result;
    };
    menuOptions.value = flattenMenu(result);
  } catch (error) {
    ElMessage.error('加载菜单选项失败');
  }
};

const handleSearch = () => {
  pagination.page = 1;
  loadData();
};

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

const handleSizeChange = (size: number) => {
  pagination.limit = size;
  loadData();
};

const handleCurrentChange = (page: number) => {
  pagination.page = page;
  loadData();
};

const handleSelectionChange = (selection: Permission[]) => {
  selectedRows.value = selection;
};

const handleAdd = async () => {
  isEdit.value = false;
  await loadMenuOptions();
  resetForm();
  dialogVisible.value = true;
};

const handleEdit = async (row: Permission) => {
  isEdit.value = true;
  await loadMenuOptions();
  Object.assign(formData, {
    permissionId: row.permissionId,
    name: row.name,
    code: row.code,
    type: row.type,
    resource: row.resource,
    method: row.method,
    menuId: row.menuId,
    sort: row.sort,
    status: row.status,
    description: row.description,
  });
  dialogVisible.value = true;
};

const handleDelete = async (row: Permission) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除权限 "${row.name}" 吗？`,
      '确认删除',
      {
        type: 'warning',
      }
    );
    await deletePermissionApi(row.permissionId);
    ElMessage.success('删除成功');
    loadData();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败');
    }
  }
};

const handleBatchDelete = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedRows.value.length} 个权限吗？`,
      '确认删除',
      {
        type: 'warning',
      }
    );
    const permissionIds = selectedRows.value.map(row => row.permissionId);
    await batchDeletePermissionApi(permissionIds);
    ElMessage.success('删除成功');
    loadData();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败');
    }
  }
};

const handleSyncFromMenu = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要从菜单同步权限吗？这将根据菜单自动创建对应的权限。',
      '确认同步',
      {
        type: 'info',
      }
    );
    const result = await syncPermissionFromMenuApi();
    ElMessage.success(`同步成功，新增 ${result.created} 个权限，更新 ${result.updated} 个权限`);
    loadData();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('同步失败');
    }
  }
};

const handleTypeChange = (type: string) => {
  // 根据类型清空相关字段
  if (type !== 'api') {
    formData.method = '';
  }
};

const handleSubmit = async () => {
  if (!formRef.value) return;
  
  try {
    await formRef.value.validate();
    submitLoading.value = true;
    
    if (isEdit.value) {
      const updateData: UpdatePermissionParams = {
        permissionId: formData.permissionId!,
        name: formData.name,
        code: formData.code,
        type: formData.type,
        resource: formData.resource,
        method: formData.method,
        menuId: formData.menuId,
        sort: formData.sort,
        status: formData.status,
        description: formData.description,
      };
      await updatePermissionApi(updateData);
      ElMessage.success('更新成功');
    } else {
      const createData: CreatePermissionParams = {
        name: formData.name,
        code: formData.code,
        type: formData.type,
        resource: formData.resource,
        method: formData.method,
        menuId: formData.menuId,
        sort: formData.sort,
        status: formData.status,
        description: formData.description,
      };
      await createPermissionApi(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, {
    permissionId: undefined,
    name: '',
    code: '',
    type: 'button',
    resource: '',
    method: '',
    menuId: undefined,
    sort: 0,
    status: 1,
    description: '',
  });
};

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

<style scoped>
.permission-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);
}

.pagination-wrapper {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}
</style>