<script lang="ts" setup>
/**
 * 角色工作台模块配置抽屉：勾选模块 + 上移/下移排序，保存调 batch-save
 * 为什么用上下移而不是拖拽：模块总数少（≤7 个），箭头排序更轻，无需引 SortableJS
 */
import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { IconifyIcon as VbenIcon } from '@vben/icons';

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

import {
  batchSaveWorkbenchWidget,
  getWorkbenchWidgetByRoleId,
  getWorkbenchWidgetOptions,
} from '../api';

/** 模块字典项 */
type WidgetOption = {
  code: string;
  label: string;
};

const record = ref<any>({});
const options = ref<WidgetOption[]>([]);
/** 已启用的模块 code（数组顺序即展示顺序） */
const enabledCodes = ref<string[]>([]);

const drawerTitle = computed(() => {
  const roleName = record.value?.name || '';
  return roleName ? `工作台模块 - ${roleName}` : '工作台模块';
});

/** 未启用的模块（供勾选添加） */
const disabledOptions = computed(() =>
  options.value.filter((item) => !enabledCodes.value.includes(item.code)),
);

/**
 * code → 中文名
 */
function labelOf(code: string) {
  return options.value.find((item) => item.code === code)?.label || code;
}

/**
 * 勾选/取消某模块
 */
function toggle(code: string, checked: boolean) {
  if (checked) {
    if (!enabledCodes.value.includes(code)) {
      enabledCodes.value.push(code);
    }
  } else {
    enabledCodes.value = enabledCodes.value.filter((item) => item !== code);
  }
}

/**
 * 上移/下移调整顺序（offset -1 上移 / 1 下移）
 */
function move(index: number, offset: number) {
  const target = index + offset;
  if (target < 0 || target >= enabledCodes.value.length) return;
  const list = [...enabledCodes.value];
  const [item] = list.splice(index, 1);
  list.splice(target, 0, item!);
  enabledCodes.value = list;
}

/**
 * 拉取字典 + 角色已配置模块
 */
async function fetchData() {
  const roleId = Number(record.value?.id || 0);
  if (!roleId) return;
  try {
    const [opts, layout] = await Promise.all([
      getWorkbenchWidgetOptions(),
      getWorkbenchWidgetByRoleId(roleId),
    ]);
    options.value = Array.isArray(opts) ? opts : [];
    enabledCodes.value = (Array.isArray(layout) ? layout : []).map(
      (item: any) => item.widget_code,
    );
  } catch {
    message.error('获取工作台模块配置失败');
    options.value = [];
    enabledCodes.value = [];
  }
}

/**
 * 保存配置（空数组表示清空该角色全部模块）
 */
async function handleSave() {
  const roleId = Number(record.value?.id || 0);
  if (!roleId) {
    message.error('角色ID不能为空');
    return;
  }
  DrawerApi.lock();
  try {
    await batchSaveWorkbenchWidget({
      role_id: roleId,
      widget_codes: enabledCodes.value,
    });
    message.success('保存成功');
    DrawerApi.close();
  } catch {
    message.error('保存失败');
  } finally {
    DrawerApi.unlock();
  }
}

const [Drawer, DrawerApi] = useVbenDrawer({
  onOpenChange(isOpen) {
    if (isOpen) {
      record.value = DrawerApi.getData()?.record || {};
      options.value = [];
      enabledCodes.value = [];
      DrawerApi.setState({ loading: true });
      fetchData().finally(() => {
        DrawerApi.setState({ loading: false });
      });
    }
  },
  onConfirm: handleSave,
});

defineExpose({
  DrawerApi,
});
</script>

<template>
  <Drawer :title="drawerTitle" class="w-[420px]">
    <div class="widget-config">
      <div class="widget-config__section-title">已启用（自上而下为展示顺序）</div>
      <div v-if="enabledCodes.length > 0" class="widget-config__list">
        <div
          v-for="(code, index) in enabledCodes"
          :key="code"
          class="widget-config__row"
        >
          <span class="widget-config__label">{{ labelOf(code) }}</span>
          <span class="widget-config__ops">
            <Button
              :disabled="index === 0"
              size="small"
              type="text"
              @click="move(index, -1)"
            >
              <VbenIcon icon="lucide:arrow-up" />
            </Button>
            <Button
              :disabled="index === enabledCodes.length - 1"
              size="small"
              type="text"
              @click="move(index, 1)"
            >
              <VbenIcon icon="lucide:arrow-down" />
            </Button>
            <Button danger size="small" type="text" @click="toggle(code, false)">
              <VbenIcon icon="lucide:x" />
            </Button>
          </span>
        </div>
      </div>
      <div v-else class="widget-config__empty">未启用任何模块，工作台将为空</div>

      <div class="widget-config__section-title mt-4">可添加</div>
      <div v-if="disabledOptions.length > 0" class="widget-config__list">
        <div
          v-for="item in disabledOptions"
          :key="item.code"
          class="widget-config__row"
        >
          <Checkbox
            :checked="false"
            @update:checked="(val: boolean) => toggle(item.code, val)"
          >
            {{ item.label }}
          </Checkbox>
        </div>
      </div>
      <div v-else class="widget-config__empty">全部模块已启用</div>
    </div>
  </Drawer>
</template>

<style scoped>
.widget-config__section-title {
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.widget-config__list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.widget-config__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  background: hsl(var(--muted) / 0.25);
  border: 1px solid hsl(var(--border));
  border-radius: 6px;
}

.widget-config__label {
  font-size: 13px;
  color: hsl(var(--foreground));
}

.widget-config__ops {
  display: flex;
  gap: 2px;
  align-items: center;
}

.widget-config__empty {
  padding: 12px 0;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}
</style>
