<template>
  <a-layout-sider v-model:collapsed="collapsed" class="menu-side" :width="width">
    <div class="logo-wrapper">
      <a href="#/desktop/dashboard">
        <img :src="logoUrl" class="logo" />
      </a>
    </div>

    <a-input v-model:value="searchText" :placeholder="$t('lang.menuWidget.searchMenu')" class="menu-search" />

    <a-menu
      mode="inline" class="custom-menu" :open-keys="openKeys" :selected-keys="selectedKeys"
      @open-change="handleOpenChange"
    >
      <a-menu-item key="dashboard" style="padding-left: 20px !important;" @click="goHome">
        <template #icon>
          <HomeOutlined />
        </template>
        <span>首页</span>
      </a-menu-item>
      <a-menu-item key="approval" style="padding-left: 20px !important;" @click="goApproval">
        <template #icon>
          <AuditOutlined />
        </template>
        <span>OA审批</span>
      </a-menu-item>

      <template v-for="rootNode in filteredMenu" :key="rootNode.key">
        <a-sub-menu :title="Language.getMenuNameTrl($i18n.locale, rootNode)">
          <template #icon>
            <i :class="rootNode.icon" />
          </template>
          <template v-for="subNode in rootNode.children" :key="subNode.key">
            <menu-node :model="subNode" />
          </template>
        </a-sub-menu>
      </template>
    </a-menu>
  </a-layout-sider>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick, defineProps } from 'vue';
import { HomeOutlined, AuditOutlined } from '@ant-design/icons-vue';
import Common from '../common/Common.js';
import Language from '../common/Language.js';
import MenuNode from './MenuNode.vue';
import { useRoleStateSingleton } from './RoleState.js';
import { Uuid } from 'pc-component-v3';
import { useRouter } from 'vue-router';
import { menuClickedEvent } from '../common/eventBus.js';

const props = defineProps({
  width: {
    type: Number,
    default: 230,
  },
  isShowMenu: {
    type: Boolean,
    default: false,
  },
});
const roleStateInstance = useRoleStateSingleton;
const searchText = ref('');
const openKeys = ref([]);
const selectedKeys = ref([]);
const collapsed = ref(false);
const rootNodes = ref([]);
const logoUrl = ref('');
const router = useRouter();
// 数据加载
const loadMenuData = () => {
  rootNodes.value = [];
  $.ajax({
    url: Common.getApiURL('MenuResourceV2/listCanVist'),
    type: 'POST',
    data: roleStateInstance.userRoleOrTemplate.value == null ? null : JSON.stringify(roleStateInstance.userRoleOrTemplate.value),
    dataType: 'json',
    contentType: 'application/json',
    beforeSend: request => Common.addTokenToRequest(request),
    success: data => {
      $.ajax({
        url: Common.getApiURL('UserMenuResource/queryAddMenus'),
        type: 'get',
        dataType: 'json',
        beforeSend: request => Common.addTokenToRequest(request),
        success: data1 => {
          data1 ? formateCollectionMenuData(data, data1) : formateMenuData(data);
        },
        error: Common.processException,
      });
    },
    error: Common.processException,
  });
};

// 格式化菜单数据
const formateMenuData = datas => {
  if (!datas?.length) return;
  initNode(datas);
  rootNodes.value = processMenuData(datas);
};

// 格式化收藏菜单数据
const formateCollectionMenuData = (datas, collections) => {
  if (
    (datas == null || datas.length == 0) &&
    (collections == null || collections.length == 0)
  ) {
    return;
  }
  initNode(datas, collections);
  rootNodes.value = processMenuData(datas);
};

// 初始化节点
const initNode = (nodes, collectionDatas = []) => {
  nodes.forEach(node => {
    node.key = Uuid.createUUID();
    node.show = true;
    node.expand = false;
    node.children = node.subMenus || [];
    node.favorite = collectionDatas.some(c => c.no === node.no);
    if (node.children.length) initNode(node.children, collectionDatas);
  });
};

// 处理菜单数据结构
const processMenuData = data => {
  return data.sort((a, b) => (a.sortNo || 0) - (b.sortNo || 0));
};

// 搜索功能
const filteredMenu = computed(() => {
  if (!searchText.value) {
    return rootNodes.value;
  }

  const searchTerm = searchText.value.toLowerCase();

  const filterTree = nodes => {
    return nodes.reduce((result, node) => {
      const nodeCopy = { ...node };

      // 处理子节点
      let childrenMatches = [];
      if (nodeCopy.children?.length) {
        childrenMatches = filterTree([...nodeCopy.children]);
      }

      // 当前节点匹配条件
      const nameMatch = (node.name || '').toLowerCase().includes(searchTerm);
      const nameEngMatch = (node.nameEng || '').toLowerCase().includes(searchTerm);
      const isSelfMatch = nameMatch || nameEngMatch;

      // 如果当前节点或子节点有匹配
      if (isSelfMatch || childrenMatches.length > 0) {
        // 构造新节点（只保留匹配的子节点）
        const newNode = {
          ...nodeCopy,
          children: childrenMatches,
        };

        if (isSelfMatch || newNode.children?.length) {
          result.push(newNode);
        }
      }
      return result;
    }, []);
  };

  return filterTree(JSON.parse(JSON.stringify(rootNodes.value)));
});

// 处理菜单展开
const handleOpenChange = keys => {
  openKeys.value = keys;
};

// 获取系统logo
const getLogoName = () => {
  $.ajax({
    type: 'GET',
    url: Common.getApiURL('clientLogoResource/selectByClientId?logoName=menuLogoName'),
    dataType: 'json',
    beforeSend: request => Common.addTokenToRequest(request),
    success: res => {
      if (res.errorCode === 0) {
        logoUrl.value = `/Files/${res.data.filePath}${res.data.imageName}`;
      }
    },
    error: Common.processException,
  });
};

// 跳转首页
const goHome = () => {
  router.push('/desktop/dashboard');
};

// 跳转OA审批
const goApproval = () => {
  const menuInfo = {
    title: 'OA审批',
    menuNodeType: 'STATIC',
    no: 'approval',
  };
  router.push('/desktop/formCenter');
  nextTick(() => {
    setTimeout(() => {
      menuClickedEvent.value = {
        path: router.currentRoute.value.fullPath,
        menuInfo,
      };
    }, 50);
  });
};

// 监听角色就绪 — 首次加载入口
watch(roleStateInstance.roleReady, ready => {
  if (ready && props.isShowMenu) {
    loadMenuData();
  }
});

// 监听角色状态变化 — 仅在角色已就绪后响应（用户手动切换角色）
watch(roleStateInstance.userRoleOrTemplate, (newVal, oldVal) => {
  if (!roleStateInstance.roleReady.value) return;
  if (newVal || newVal === null) loadMenuData();
  if (newVal && oldVal && newVal.roleOrTemplateName !== oldVal.roleOrTemplateName) {
    router.push('/desktop/dashboard');
  }
  if (newVal === null) router.push('/desktop/dashboard');
});

watch(() => props.isShowMenu, (newVal, oldVal) => {
  if (newVal) {
    loadMenuData();
  }
});

// 监听搜索框输入
watch(searchText, () => {
  if (!searchText.value) {
    openKeys.value = [];
    return;
  }

  const parentKeys = new Set();
  const searchTerm = searchText.value.toLowerCase();

  const collectParentKeys = (nodes, parentChain = []) => {
    nodes.forEach(node => {
      const currentChain = [...parentChain];

      if (node.children?.length) {
        currentChain.push(node.key);
        collectParentKeys(node.children, currentChain);
      }

      const nameMatch = (node.name || '').toLowerCase().includes(searchTerm);
      const nameEngMatch = (node.nameEng || '').toLowerCase().includes(searchTerm);
      const isMatch = nameMatch || nameEngMatch;

      if (isMatch || (node.children?.length && node.children.some(c => c.show))) {
        currentChain.forEach(key => parentKeys.add(key));
      }
    });
  };

  collectParentKeys(filteredMenu.value);
  openKeys.value = Array.from(parentKeys);
});

onMounted(() => {
  getLogoName();
  // 防御：若 MenuWidget 挂载时 roleReady 已为 true（极端时序），直接加载
  if (roleStateInstance.roleReady.value) {
    loadMenuData();
  }
});

</script>

<style scoped>
.menu-side {
  overflow: auto;
  height: 100vh;
  position: fixed;
  left: 0;
  background: var(--menu-side-background-color) !important;
}

.logo-wrapper {
  padding: 16px;
  text-align: center;
}

.logo {
  width: var(--menu-logo-width);
}

.menu-search {
  margin: 8px 8px 8px 16px;
  width: calc(100% - 32px);
  background-color: var(--menu-search-input-background-color) !important;
}

:deep(.menu-search, .ant-input) {
  color: #fff !important;
  background-color: var(--menu-search-input-background-color) !important;
}

:deep(.ant-input::placeholder) {
  color: #ccc !important;
}

/* 菜单容器基础样式 */
:deep(.custom-menu) {
  background: transparent;
  border-right: 0;
}

/* 菜单项通用样式 */
:deep(.ant-menu-submenu-title),
:deep(.ant-menu-item) {
  color: #fff;
  font-weight: 500;
}

:deep(.ant-menu-submenu .ant-menu-submenu-inline .ant-menu-submenu-title) {
  padding-left: 34px !important;
}

:deep(.ant-menu .ant-menu-sub .ant-menu-inline .ant-menu-item) {
  padding-left: 46px !important;
}

/* 末级菜单项悬停样式 */
:deep(.ant-menu-item:only-child:hover),
:deep(.ant-menu-item:not(.ant-menu-submenu-title):hover) {
  color: #fff !important;
  background: var(--menu-select-color) !important;
}

/* 父级菜单悬停样式 */
:deep(.ant-menu-submenu-title:hover) {
  color: #fff !important;
  background: var(--menu-select-color) !important;
}

/* 箭头样式 */
:deep(.ant-menu-submenu-arrow) {
  color: rgba(255, 255, 255, 0.65);
}

/* 父级菜单布局 */
:deep(.ant-menu-submenu-title) {
  display: flex;
  align-items: center;
}
</style>