/**
 * Menu Store
 *
 * 管理菜单状态和用户菜单权限
 */
import { defineStore } from 'pinia';
import { ref, computed, type Ref } from 'vue';
import type { MenuTree } from '../types/menu';
import type { IRequestAdapter } from '../adapters/request/interface';
import { logger } from '../utils/logger';

// 全局请求适配器实例
let requestAdapter: IRequestAdapter;

/**
 * 设置请求适配器
 */
export function setMenuRequestAdapter(adapter: IRequestAdapter) {
  requestAdapter = adapter;
}

export const useMenuStore = defineStore('menu', () => {
  // State
  const menus: Ref<MenuTree[]> = ref([]);
  const loading = ref(false);
  const error: Ref<string | null> = ref(null);

  // Computed
  const flatMenus = computed(() => {
    const flatten = (items: MenuTree[]): MenuTree[] => {
      return items.reduce((acc, item) => {
        acc.push(item);
        if (item.children && item.children.length > 0) {
          acc.push(...flatten(item.children));
        }
        return acc;
      }, [] as MenuTree[]);
    };
    return flatten(menus.value);
  });

  const activeMenus = computed(() => {
    return flatMenus.value.filter((menu) => menu.is_active);
  });

  /**
   * 获取用户菜单
   */
  const fetchUserMenus = async (): Promise<void> => {
    try {
      loading.value = true;
      error.value = null;
      logger.info('MenuStore', 'Fetching user menus');

      const response = await requestAdapter.get<MenuTree[]>('/api/v1/menus/my');
      menus.value = response.data;

      logger.info('MenuStore', 'User menus loaded', { count: menus.value.length });
    } catch (err: any) {
      error.value = err.message || '获取菜单失败';
      logger.error('MenuStore', 'Failed to fetch user menus', err);
      throw err;
    } finally {
      loading.value = false;
    }
  };

  /**
   * 获取菜单树
   */
  const fetchMenuTree = async (): Promise<void> => {
    try {
      loading.value = true;
      error.value = null;
      logger.info('MenuStore', 'Fetching menu tree');

      const response = await requestAdapter.get<MenuTree[]>('/api/v1/menus/tree');
      menus.value = response.data;

      logger.info('MenuStore', 'Menu tree loaded', { count: menus.value.length });
    } catch (err: any) {
      error.value = err.message || '获取菜单树失败';
      logger.error('MenuStore', 'Failed to fetch menu tree', err);
      throw err;
    } finally {
      loading.value = false;
    }
  };

  /**
   * 检查是否有菜单访问权限
   */
  const hasMenuAccess = (menuCode: string): boolean => {
    return flatMenus.value.some((menu) => menu.code === menuCode && menu.is_active);
  };

  /**
   * 根据 code 查找菜单
   */
  const findMenuByCode = (code: string): MenuTree | undefined => {
    return flatMenus.value.find((menu) => menu.code === code);
  };

  /**
   * 根据 path 查找菜单
   */
  const findMenuByPath = (path: string): MenuTree | undefined => {
    return flatMenus.value.find((menu) => menu.path === path);
  };

  /**
   * 清空菜单
   */
  const clearMenus = (): void => {
    menus.value = [];
    error.value = null;
  };

  return {
    // State
    menus,
    loading,
    error,

    // Computed
    flatMenus,
    activeMenus,

    // Actions
    fetchUserMenus,
    fetchMenuTree,
    hasMenuAccess,
    findMenuByCode,
    findMenuByPath,
    clearMenus,
  };
});
