<script setup lang="ts">
import type { VNode } from 'vue';
import { computed, ref } from 'vue';
import { objectContextDomainConfigs } from '@/constants/object-context';
import { useRouteStore } from '@/store/modules/route';
import { useWorkbenchStore } from '@/store/modules/workbench';
import { useRouterPush } from '@/hooks/common/router';
import { useWorkbenchRefresh } from '../composables/use-workbench-refresh';
import WorkbenchModuleCard from './workbench-module-card.vue';
import WorkbenchShortcutPicker from './workbench-shortcut-picker.vue';

interface Props {
  editing?: boolean;
}

withDefaults(defineProps<Props>(), {
  editing: false
});

defineEmits<{
  (e: 'hide'): void;
}>();

const routeStore = useRouteStore();
const workbench = useWorkbenchStore();
const { routerPushByKey } = useRouterPush();

const { loading, refresh } = useWorkbenchRefresh();

interface FlatMenu {
  key: string;
  label: string;
  /** 来自 routeStore.menus 的 icon VNode（SvgIconVNode 渲染产物，与侧栏菜单同源） */
  icon?: VNode;
}

// 与 picker 保持一致：对象域入口（project_list / product_list）当叶子，
// 其下的对象上下文页不进入快捷入口候选范围。
const OBJECT_DOMAIN_ENTRY_KEYS = new Set(objectContextDomainConfigs.map(c => c.entryRouteKey));

function flatten(menus: typeof routeStore.menus): FlatMenu[] {
  const out: FlatMenu[] = [];
  function walk(list: typeof menus) {
    list.forEach((m: any) => {
      const isDomainEntry = OBJECT_DOMAIN_ENTRY_KEYS.has(m.key);
      const hasChildren = !isDomainEntry && m.children && m.children.length > 0;
      if (hasChildren) {
        walk(m.children);
      } else {
        out.push({
          key: m.key,
          label: m.label as string,
          icon: m.icon
        });
      }
    });
  }
  walk(menus);
  return out;
}

const flatMenus = computed(() => flatten(routeStore.menus));
const selectedKeys = computed(() => workbench.layout.settings.shortcut?.menuKeys ?? []);
const selected = computed(() =>
  selectedKeys.value.map(k => flatMenus.value.find(m => m.key === k)).filter((x): x is FlatMenu => Boolean(x))
);

const pickerOpen = ref(false);

function openPicker() {
  pickerOpen.value = true;
}

function handleClick(key: string) {
  routerPushByKey(key as any);
}

function handleConfirm(keys: string[]) {
  workbench.updateModuleSettings('shortcut', { menuKeys: keys });
}

function handleRemove(key: string) {
  workbench.updateModuleSettings('shortcut', { menuKeys: selectedKeys.value.filter(k => k !== key) });
}
</script>

<template>
  <WorkbenchModuleCard
    v-loading="loading"
    title="快捷入口"
    icon="mdi:rocket-launch-outline"
    :badge-count="selected.length || undefined"
    :editing="editing"
    has-settings
    @hide="$emit('hide')"
    @open-settings="openPicker"
    @refresh="refresh"
  >
    <div v-if="selected.length === 0" class="shortcut-empty">
      <ElEmpty description="还未选择菜单" :image-size="48">
        <ElButton type="primary" size="small" @click="openPicker">+ 选择菜单</ElButton>
      </ElEmpty>
    </div>
    <div v-else class="shortcut-grid">
      <button v-for="item in selected" :key="item.key" class="shortcut-item" @click="handleClick(item.key)">
        <ElIcon v-if="item.icon" class="shortcut-item__icon">
          <component :is="item.icon" />
        </ElIcon>
        <SvgIcon v-else icon="mdi:link-variant" class="shortcut-item__icon" />
        <span class="shortcut-item__label">{{ item.label }}</span>
        <span class="shortcut-item__remove" title="移除此快捷入口" @click.stop="handleRemove(item.key)">
          <SvgIcon icon="mdi:close" />
        </span>
      </button>
      <button class="shortcut-item shortcut-item--add" title="添加快捷入口" @click="openPicker">
        <SvgIcon icon="mdi:plus" />
        <span>添加</span>
      </button>
    </div>

    <WorkbenchShortcutPicker v-model="pickerOpen" :initial-selected="selectedKeys" @confirm="handleConfirm" />
  </WorkbenchModuleCard>
</template>

<style scoped>
.shortcut-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
  flex: 1;
  min-height: 0;
  overflow: auto;
  align-content: start;
}

.shortcut-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px;
  border: 1px solid var(--el-border-color-lighter);
  background: var(--el-fill-color-lighter);
  border-radius: 8px;
  cursor: pointer;
  font-size: 12px;
  color: var(--el-text-color-primary);
  transition: all 120ms;
}

.shortcut-item__remove {
  position: absolute;
  top: 4px;
  right: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  color: var(--el-text-color-placeholder);
  font-size: 12px;
  opacity: 0;
  transition:
    opacity 120ms,
    color 120ms,
    background-color 120ms;
}

.shortcut-item:hover .shortcut-item__remove {
  opacity: 1;
}

.shortcut-item__remove:hover {
  background-color: var(--el-color-danger-light-9);
  color: var(--el-color-danger);
}

.shortcut-item__icon {
  font-size: 20px;
  color: var(--el-color-primary);
  transition: color 120ms;
}

.shortcut-item__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shortcut-item:hover {
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
}

.shortcut-item--add {
  border-style: dashed;
  border-color: var(--el-border-color);
  background: transparent;
  color: var(--el-text-color-secondary);
}

.shortcut-item--add:hover {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
}

.shortcut-empty {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 压缩 ElEmpty 默认大 padding，空态在最小高度下也不溢出 */
.shortcut-empty :deep(.el-empty) {
  padding: 12px 0;
}
</style>
