/**
 * @description Vue权限指令
 * @author yslg
 * @since 2025-10-07
 */

import type { App, DirectiveBinding } from 'vue';
import type { Store } from 'vuex';

let store: Store<any>;

/**
 * 权限指令实现
 */
const permission = {
  /**
   * 指令挂载时执行
   */
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    const { value, modifiers } = binding;
    
    if (!checkPermission(value, modifiers || {})) {
      // 无权限时移除元素
      removeElement(el);
    }
  },
  
  /**
   * 指令更新时执行
   */
  updated(el: HTMLElement, binding: DirectiveBinding) {
    const { value, modifiers } = binding;
    
    if (!checkPermission(value, modifiers || {})) {
      // 无权限时移除元素
      removeElement(el);
    }
  }
};

/**
 * 角色指令实现
 */
const role = {
  /**
   * 指令挂载时执行
   */
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    const { value, modifiers } = binding;
    
    if (!checkRole(value, modifiers || {})) {
      // 无权限时移除元素
      removeElement(el);
    }
  },
  
  /**
   * 指令更新时执行
   */
  updated(el: HTMLElement, binding: DirectiveBinding) {
    const { value, modifiers } = binding;
    
    if (!checkRole(value, modifiers || {})) {
      // 无权限时移除元素
      removeElement(el);
    }
  }
};

/**
 * 检查权限
 * @param value 权限值（字符串或字符串数组）
 * @param modifiers 修饰符
 * @returns 是否有权限
 */
function checkPermission(value: string | string[], modifiers: Partial<Record<string, boolean>>): boolean {
  if (!store) {
    console.warn('Store未初始化，权限检查失败');
    return false;
  }
  
  if (!value) {
    console.warn('权限指令缺少权限值');
    return false;
  }
  
  const permissions = Array.isArray(value) ? value : [value];
  
  // 检查修饰符
  if (modifiers?.all) {
    // 需要所有权限
    return store.getters['auth/hasAllPermissions'](permissions);
  } else {
    // 需要任意一个权限（默认行为）
    return store.getters['auth/hasAnyPermission'](permissions);
  }
}

/**
 * 检查角色
 * @param value 角色值（字符串或字符串数组）
 * @param modifiers 修饰符
 * @returns 是否有角色
 */
function checkRole(value: string | string[], modifiers: Partial<Record<string, boolean>>): boolean {
  if (!store) {
    console.warn('Store未初始化，角色检查失败');
    return false;
  }
  
  if (!value) {
    console.warn('角色指令缺少角色值');
    return false;
  }
  
  const roles = Array.isArray(value) ? value : [value];
  const userRoles = store.getters['auth/userRoles'] || [];
  
  // 检查修饰符
  if (modifiers?.all) {
    // 需要所有角色
    return roles.every(role => 
      userRoles.some((userRole: any) => userRole.code === role)
    );
  } else {
    // 需要任意一个角色（默认行为）
    return roles.some(role => 
      userRoles.some((userRole: any) => userRole.code === role)
    );
  }
}

/**
 * 移除DOM元素
 * @param el 要移除的元素
 */
function removeElement(el: HTMLElement) {
  try {
    if (el.parentNode) {
      // 使用更安全的方式移除元素
      el.style.display = 'none';
      // 延迟移除，避免Range错误
      setTimeout(() => {
        if (el.parentNode) {
          el.parentNode.removeChild(el);
        }
      }, 0);
    }
  } catch (error) {
    console.warn('移除元素时发生错误:', error);
    // 如果移除失败，至少隐藏元素
    el.style.display = 'none';
  }
}

/**
 * 注册权限指令
 * @param app Vue应用实例
 * @param storeInstance Vuex store实例
 */
export function setupPermissionDirectives(app: App, storeInstance: Store<any>) {
  store = storeInstance;
  
  // 注册v-permission指令
  app.directive('permission', permission);
  
  // 注册v-role指令  
  app.directive('role', role);
  
  // 注册v-auth指令（permission的别名）
  app.directive('auth', permission);
}

/**
 * 权限检查Composition API
 */
export function usePermission() {
  return {
    /**
     * 检查是否有指定权限
     */
    hasPermission: (permissionCode: string): boolean => {
      if (!store) return false;
      return store.getters['auth/hasPermission'](permissionCode);
    },
    
    /**
     * 检查是否有任意一个权限
     */
    hasAnyPermission: (permissionCodes: string[]): boolean => {
      if (!store) return false;
      return store.getters['auth/hasAnyPermission'](permissionCodes);
    },
    
    /**
     * 检查是否有所有权限
     */
    hasAllPermissions: (permissionCodes: string[]): boolean => {
      if (!store) return false;
      return store.getters['auth/hasAllPermissions'](permissionCodes);
    },
    
    /**
     * 检查是否有指定角色
     */
    hasRole: (roleCode: string): boolean => {
      if (!store) return false;
      const userRoles = store.getters['auth/userRoles'] || [];
      return userRoles.some((role: any) => role.code === roleCode);
    },
    
    /**
     * 检查是否有任意一个角色
     */
    hasAnyRole: (roleCodes: string[]): boolean => {
      if (!store) return false;
      const userRoles = store.getters['auth/userRoles'] || [];
      return roleCodes.some(code => 
        userRoles.some((role: any) => role.code === code)
      );
    },
    
    /**
     * 检查是否有所有角色
     */
    hasAllRoles: (roleCodes: string[]): boolean => {
      if (!store) return false;
      const userRoles = store.getters['auth/userRoles'] || [];
      return roleCodes.every(code => 
        userRoles.some((role: any) => role.code === code)
      );
    }
  };
}

