<script setup lang="ts">
import type { VxeGridProps } from '#/adapter/vxe-table';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui';
import { getAdminListApi } from '#/api/core/admin.user';
import {
  getUserGroupListApi,
  getUserGroupsApi,
  setUserGroupsApi,
  getUserRolesApi,
  getUserRolesBatchApi,
  getPermissionListApi,
  getUserPermissionsDirectApi,
  setUserPermissionsDirectApi,
} from '#/api/core/permission';
import type { PermissionApi } from '#/api/core/permission';
import type { UserInfo } from '#/model/admin.user';
import {
  Button, Card, Space, Tag, Spin, message,
  Modal, Tabs, TabPane, Transfer,
} from 'ant-design-vue';
import { computed, onActivated, ref } from 'vue';

// ─── 行级缓存（用户组、角色）─────────────────────────────
const currentUsers = ref<UserInfo[]>([]);
const userGroupsMap = ref<Map<number, PermissionApi.UserGroup[]>>(new Map());
const userRolesMap = ref<Map<number, PermissionApi.Role[]>>(new Map());

async function loadRowDataForList(users: UserInfo[]) {
  const ids = users.map((u) => u.id).filter((id): id is number => id != null);
  const [groupResults, roleResults] = await Promise.all([
    Promise.allSettled(ids.map((id) => getUserGroupsApi(id))),
    getUserRolesBatchApi(ids),
  ]);
  const gMap = new Map<number, PermissionApi.UserGroup[]>();
  const rMap = new Map<number, PermissionApi.Role[]>();
  ids.forEach((id, i) => {
    if (groupResults[i]!.status === 'fulfilled') gMap.set(id, (groupResults[i] as any).value || []);
    rMap.set(id, roleResults?.[String(id)] || []);
  });
  userGroupsMap.value = gMap;
  userRolesMap.value = rMap;
}

async function refreshUserRelationCache(adminId: number) {
  const [groups, roles] = await Promise.all([
    getUserGroupsApi(adminId),
    getUserRolesApi(adminId),
  ]);
  userGroupsMap.value = new Map(userGroupsMap.value).set(adminId, groups || []);
  userRolesMap.value = new Map(userRolesMap.value).set(adminId, roles || []);
}

// ─── 分配弹窗 ─────────────────────────────────────────────
const modalOpen = ref(false);
const modalLoading = ref(false);
const activeTab = ref('groups');
const currentAdminId = ref<number | null>(null);
const currentAdminName = ref('');

// 用户组 Transfer
const allGroups = ref<PermissionApi.UserGroup[]>([]);
const selectedGroupIds = ref<string[]>([]);
const groupTransferData = computed(() =>
  allGroups.value.map((g) => ({
    key: String(g.id),
    title: `${g.group_name}（${g.group_code}）`,
    disabled: g.status !== 1,
  })),
);

// 单点权限 Transfer（allow/deny 两个列表，以 allow 为主）
const allPermissions = ref<PermissionApi.Permission[]>([]);
const selectedAllowPermIds = ref<string[]>([]);
const selectedDenyPermIds = ref<string[]>([]);
const permissionTransferData = computed(() =>
  allPermissions.value.map((p) => ({
    key: String(p.id),
    title: `${p.permission_name}（${p.permission_code}）`,
    description: p.api_path ? `${p.http_method ?? ''} ${p.api_path}` : '',
    disabled: p.status !== 1,
  })),
);

async function openAssignModal(row: UserInfo) {
  if (!row.id) {
    message.warning('该用户缺少 ID，无法分配权限');
    return;
  }
  currentAdminId.value = row.id;
  currentAdminName.value = row.username;
  activeTab.value = 'groups';
  modalLoading.value = true;
  modalOpen.value = true;
  try {
    const [groupsRes, permsRes, userGroups, userDirectPerms, userRoles] = await Promise.all([
      getUserGroupListApi({ page: 1, pageSize: 500 }),
      getPermissionListApi({ page: 1, pageSize: 500 }),
      getUserGroupsApi(row.id),
      getUserPermissionsDirectApi(row.id),
      getUserRolesApi(row.id),
    ]);
    console.log('userGroups', userGroups);
    allGroups.value = groupsRes.items || [];
    allPermissions.value = permsRes.items || [];
    selectedGroupIds.value = (userGroups || []).map((g) => String(g.id));
    userGroupsMap.value = new Map(userGroupsMap.value).set(row.id, userGroups || []);
    userRolesMap.value = new Map(userRolesMap.value).set(row.id, userRoles || []);
    const directPerms = userDirectPerms || [];
    selectedAllowPermIds.value = directPerms.filter((p) => p.grant_type === 1).map((p) => String(p.permission_id));
    selectedDenyPermIds.value = directPerms.filter((p) => p.grant_type === 2).map((p) => String(p.permission_id));
  } catch {
    message.error('加载权限数据失败');
  } finally {
    modalLoading.value = false;
  }
}

async function handleConfirm() {
  if (currentAdminId.value == null) return;
  modalLoading.value = true;
  try {
    const allowPerms = selectedAllowPermIds.value.map((id) => ({ permission_id: Number(id), grant_type: 1 as const }));
    const denyPerms = selectedDenyPermIds.value.map((id) => ({ permission_id: Number(id), grant_type: 2 as const }));
    await Promise.all([
      setUserGroupsApi({ admin_id: currentAdminId.value, group_ids: selectedGroupIds.value.map(Number) }),
      setUserPermissionsDirectApi({ admin_id: currentAdminId.value, permissions: [...allowPerms, ...denyPerms] }),
    ]);
    message.success('权限分配成功');
    modalOpen.value = false;
    await refreshUserRelationCache(currentAdminId.value);
  } finally {
    modalLoading.value = false;
  }
}

// ─── 表格 ──────────────────────────────────────────────────
const gridOptions: VxeGridProps<UserInfo> = {
  columns: [
    { field: 'id', title: 'ID', width: 80 },
    { field: 'username', title: '用户名', width: 160 },
    { field: 'phone', title: '手机号', width: 140 },
    { field: 'email', title: '邮箱', minWidth: 160 },
    { field: 'userGroups', title: '用户组', minWidth: 200, slots: { default: 'userGroupsSlot' } },
    { field: 'userRoles', title: '权限组（角色）', minWidth: 200, slots: { default: 'userRolesSlot' } },
    { fixed: 'right', slots: { default: 'actionSlot' }, title: '操作', width: 120 },
  ],
  minHeight: 650,
  pagerConfig: {},
  proxyConfig: {
    response: { total: 'total', result: 'data' },
    ajax: {
      query: async () => {
        const result = await getAdminListApi();
        const list: UserInfo[] = Array.isArray(result) ? result : ((result as any)?.data ?? []);
        currentUsers.value = list;
        void loadRowDataForList(list);
        return result;
      },
    },
  },
  rowConfig: { isHover: true },
};

const [Grid, GridApi] = useVbenVxeGrid({ gridOptions });

onActivated(() => {
  if (currentUsers.value.length > 0) {
    void loadRowDataForList(currentUsers.value);
  }
});
</script>

<template>
  <Page auto-content-height>
    <!-- 分配弹窗 -->
    <Modal
      v-model:open="modalOpen"
      :confirm-loading="modalLoading"
      :title="`权限分配 — ${currentAdminName}`"
      width="800px"
      @ok="handleConfirm"
    >
      <Spin :spinning="modalLoading">
        <Tabs v-model:activeKey="activeTab">
          <!-- 用户组分配 -->
          <TabPane key="groups" tab="用户组分配">
            <p class="mb-3 text-gray-500 text-sm">将用户组分配给该管理员（继承用户组内的权限组）：</p>
            <Transfer
              v-model:target-keys="selectedGroupIds"
              :data-source="groupTransferData"
              :render="(item: any) => item.title"
              :titles="['可选用户组', '已选用户组']"
              show-search
              :list-style="{ width: '100%', height: '280px' }"
            />
          </TabPane>

          <!-- 单点权限：允许 -->
          <TabPane key="allow" tab="单点权限（允许）">
            <p class="mb-3 text-gray-500 text-sm">直接授予该用户的单点权限（grant_type=1，优先级高于角色）：</p>
            <Transfer
              v-model:target-keys="selectedAllowPermIds"
              :data-source="permissionTransferData"
              :render="(item: any) => item.title"
              :titles="['可选权限', '已允许']"
              show-search
              :list-style="{ width: '100%', height: '280px' }"
            />
          </TabPane>

          <!-- 单点权限：拒绝 -->
          <TabPane key="deny" tab="单点权限（拒绝）">
            <p class="mb-3 text-gray-500 text-sm">明确拒绝该用户的单点权限（grant_type=2，可覆盖角色授权）：</p>
            <Transfer
              v-model:target-keys="selectedDenyPermIds"
              :data-source="permissionTransferData"
              :render="(item: any) => item.title"
              :titles="['可选权限', '已拒绝']"
              show-search
              :list-style="{ width: '100%', height: '280px' }"
            />
          </TabPane>
        </Tabs>
      </Spin>
    </Modal>

    <Card class="mb-4" title="用户权限分配">
      <template #extra>
        <Button @click="GridApi.reload()">刷新</Button>
      </template>
    </Card>

    <Grid>
      <template #userGroupsSlot="{ row }">
        <Space wrap>
          <template v-if="row.id && userGroupsMap.get(row.id)?.length">
            <Tag v-for="g in userGroupsMap.get(row.id)" :key="g.id" color="blue">{{ g.group_name }}</Tag>
          </template>
          <span v-else class="text-gray-400 text-xs">未分配</span>
        </Space>
      </template>
      <template #userRolesSlot="{ row }">
        <Space wrap>
          <template v-if="row.id && userRolesMap.get(row.id)?.length">
            <Tag v-for="r in userRolesMap.get(row.id)" :key="r.id" color="purple">{{ r.role_name }}</Tag>
          </template>
          <span v-else class="text-gray-400 text-xs">无</span>
        </Space>
      </template>
      <template #actionSlot="{ row }">
        <Button size="small" type="primary" @click="openAssignModal(row)">分配权限</Button>
      </template>
    </Grid>
  </Page>
</template>
