<script lang="ts" setup>
import type { SystemRoleApi } from '#/api';

import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';

import { Button, Checkbox, message, Spin } from 'ant-design-vue';

import { getAllApiList, getRoleApiList, updateRoleApi } from '#/api';
import { $t } from '#/locales';

const emits = defineEmits(['success']);

const loading = ref(false);
const allApiList = ref<any[]>([]);
const roleApiList = ref<any[]>([]);
const selectedApiIds = ref<string[]>([]);
const formData = ref<SystemRoleApi.SystemRoleItem>();
const roleId = ref<string>();

const [Drawer, drawerApi] = useVbenDrawer({
  async onConfirm() {
    await onSave();
  },
  onOpenChange(isOpen) {
    if (isOpen) {
      const data = drawerApi.getData<SystemRoleApi.SystemRoleItem>();
      if (data) {
        formData.value = data;
        roleId.value = data.id;
        fetchRoleApiList();
      }
      fetchAllApiList();
    }
  },
});

// 计算已选中的API ID
const selectedApiIdsSet = computed(() => new Set(selectedApiIds.value));

// 获取所有API列表
async function fetchAllApiList() {
  try {
    loading.value = true;
    const response = await getAllApiList({ status: 1 }); // 只获取启用的API
    allApiList.value = response.items || [];
  } catch (error) {
    console.error('获取API列表失败:', error);
    message.error('获取API列表失败');
  } finally {
    loading.value = false;
  }
}

// 获取角色已分配的API权限
async function fetchRoleApiList() {
  if (!roleId.value) return;

  try {
    loading.value = true;
    const response = await getRoleApiList(roleId.value);
    roleApiList.value = response.items || [];
    selectedApiIds.value = roleApiList.value.map((item) => item.api_id);
  } catch (error) {
    console.error('获取角色API权限失败:', error);
    message.error('获取角色API权限失败');
  } finally {
    loading.value = false;
  }
}

// 全选/取消全选
function toggleSelectAll(e: any) {
  const checked = e.target.checked;
  selectedApiIds.value = checked
    ? allApiList.value.map((api) => api.api_id)
    : [];
}

// 判断是否全选
const isAllSelected = computed(() => {
  return (
    allApiList.value.length > 0 &&
    selectedApiIds.value.length === allApiList.value.length
  );
});

// 判断是否部分选中
const isIndeterminate = computed(() => {
  return (
    selectedApiIds.value.length > 0 &&
    selectedApiIds.value.length < allApiList.value.length
  );
});

// 保存API权限
async function onSave() {
  if (!roleId.value) return;

  try {
    loading.value = true;
    await updateRoleApi({
      role_id: roleId.value,
      api_ids: selectedApiIds.value,
    });
    message.success('API权限保存成功');
    emits('success');
    drawerApi.close();
  } catch (error) {
    console.error('保存API权限失败:', error);
    message.error('保存API权限失败');
  } finally {
    loading.value = false;
  }
}

// 重置选择
function onReset() {
  selectedApiIds.value = roleApiList.value.map((item) => item.api_id);
}

// 计算抽屉标题
const getDrawerTitle = computed(() => {
  return formData.value?.role_name
    ? `${$t('system.role.setApiPermissions')} - ${formData.value.role_name}`
    : $t('system.role.setApiPermissions');
});
</script>

<template>
  <Drawer :title="getDrawerTitle">
    <div class="p-4">
      <div class="mb-4">
        <p class="text-sm text-gray-500">
          为角色分配API访问权限，勾选的API将被允许访问
        </p>
      </div>

      <Spin :spinning="loading">
        <div class="space-y-4">
          <!-- 全选操作 -->
          <div class="flex items-center gap-4 rounded-lg bg-gray-50 p-3">
            <Checkbox :checked="isAllSelected" :indeterminate="isIndeterminate" @change="toggleSelectAll">
              全选
            </Checkbox>
            <span class="text-sm text-gray-500">
              已选择 {{ selectedApiIds.length }} / {{ allApiList.length }} 个API
            </span>
          </div>

          <!-- API列表 -->
          <div class="max-h-96 overflow-y-auto rounded-lg border">
            <div v-for="api in allApiList" :key="api.api_id"
              class="flex items-center gap-3 border-b p-3 last:border-b-0 hover:bg-gray-50">
              <Checkbox :checked="selectedApiIdsSet.has(api.api_id)" @change="
                (e) => {
                  if (e.target.checked) {
                    selectedApiIds.push(api.api_id);
                  } else {
                    const index = selectedApiIds.indexOf(api.api_id);
                    if (index > -1) {
                      selectedApiIds.splice(index, 1);
                    }
                  }
                }
              " />
              <div class="flex-1">
                <div class="flex items-center gap-2">
                  <span class="font-medium">{{ api.api_name }}</span>
                  <span class="rounded px-2 py-1 text-xs" :class="{
                    'bg-blue-100 text-blue-800': api.method === 'GET',
                    'bg-green-100 text-green-800': api.method === 'POST',
                    'bg-orange-100 text-orange-800': api.method === 'PUT',
                    'bg-red-100 text-red-800': api.method === 'DELETE',
                  }">
                    {{ api.method }}
                  </span>
                </div>
                <div class="mt-1 text-sm text-gray-500">
                  {{ api.url }}
                </div>
                <div v-if="api.description" class="mt-1 text-xs text-gray-400">
                  {{ api.description }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </Spin>

      <!-- 操作按钮 -->
      <div class="mt-6 flex justify-end gap-2">
        <Button @click="onReset"> 重置 </Button>
        <Button type="primary" @click="onSave" :loading="loading">
          保存
        </Button>
      </div>
    </div>
  </Drawer>
</template>
