/**
 * Vue directive for permission-based element visibility
 * Usage: v-can:resource.action or v-can="'resource.action'"
 * 
 * Examples:
 * <button v-can:diary.write>Bearbeiten</button>
 * <button v-can:diary.delete>Löschen</button>
 * <div v-can="'members.write'">...</div>
 */

const checkPermission = (el, binding, vnode) => {
  // Safely access store
  if (!vnode.appContext || !vnode.appContext.config || !vnode.appContext.config.globalProperties) {
    // Hide by default if store not available (deny by default)
    el.style.display = 'none';
    return;
  }
  
  const store = vnode.appContext.config.globalProperties.$store;
  
  if (!store) {
    // Hide by default if store not found (deny by default)
    el.style.display = 'none';
    return;
  }
  
  let resource, action;
  
  // Parse directive value
  if (typeof binding.value === 'string') {
    // v-can="'diary.write'"
    [resource, action] = binding.value.split('.');
  } else if (binding.arg) {
    // v-can:diary.write
    resource = binding.arg;
    action = Object.keys(binding.modifiers)[0] || 'read';
  } else {
    el.style.display = 'none';
    return;
  }
  
  const hasPermission = store.getters.hasPermission(resource, action);
  
  if (hasPermission) {
    el.style.display = '';
  } else {
    el.style.display = 'none';
  }
};

export const canDirective = {
  mounted(el, binding, vnode) {
    // Initial check
    checkPermission(el, binding, vnode);
    
    // Set up watcher for permissions changes
    if (vnode.appContext && vnode.appContext.config && vnode.appContext.config.globalProperties) {
      const store = vnode.appContext.config.globalProperties.$store;
      if (store) {
        // Watch both permissions and currentClub
        el._permissionUnwatch = store.subscribe((mutation) => {
          if (mutation.type === 'setPermissions' || mutation.type === 'setClub') {
            checkPermission(el, binding, vnode);
          }
        });
      }
    }
  },
  
  updated(el, binding, vnode) {
    checkPermission(el, binding, vnode);
  },
  
  unmounted(el) {
    // Clean up watcher
    if (el._permissionUnwatch) {
      el._permissionUnwatch();
      delete el._permissionUnwatch;
    }
  }
};

/**
 * Directive for admin-only elements
 * Usage: v-admin
 */
const checkAdmin = (el, vnode) => {
  if (!vnode.appContext || !vnode.appContext.config || !vnode.appContext.config.globalProperties) {
    el.style.display = 'none';
    return;
  }
  
  const store = vnode.appContext.config.globalProperties.$store;
  
  if (!store) {
    el.style.display = 'none';
    return;
  }
  
  const isOwner = store.getters.isClubOwner;
  const role = store.getters.userRole;
  
  if (isOwner || role === 'admin') {
    el.style.display = '';
  } else {
    el.style.display = 'none';
  }
};

export const adminDirective = {
  mounted(el, binding, vnode) {
    checkAdmin(el, vnode);
    
    if (vnode.appContext && vnode.appContext.config && vnode.appContext.config.globalProperties) {
      const store = vnode.appContext.config.globalProperties.$store;
      if (store) {
        el._adminUnwatch = store.subscribe((mutation) => {
          if (mutation.type === 'setPermissions' || mutation.type === 'setClub') {
            checkAdmin(el, vnode);
          }
        });
      }
    }
  },
  
  updated(el, binding, vnode) {
    checkAdmin(el, vnode);
  },
  
  unmounted(el) {
    if (el._adminUnwatch) {
      el._adminUnwatch();
      delete el._adminUnwatch;
    }
  }
};

/**
 * Directive for owner-only elements
 * Usage: v-owner
 */
const checkOwner = (el, vnode) => {
  if (!vnode.appContext || !vnode.appContext.config || !vnode.appContext.config.globalProperties) {
    el.style.display = 'none';
    return;
  }
  
  const store = vnode.appContext.config.globalProperties.$store;
  
  if (!store) {
    el.style.display = 'none';
    return;
  }
  
  const isOwner = store.getters.isClubOwner;
  
  if (isOwner) {
    el.style.display = '';
  } else {
    el.style.display = 'none';
  }
};

export const ownerDirective = {
  mounted(el, binding, vnode) {
    checkOwner(el, vnode);
    
    if (vnode.appContext && vnode.appContext.config && vnode.appContext.config.globalProperties) {
      const store = vnode.appContext.config.globalProperties.$store;
      if (store) {
        el._ownerUnwatch = store.subscribe((mutation) => {
          if (mutation.type === 'setPermissions' || mutation.type === 'setClub') {
            checkOwner(el, vnode);
          }
        });
      }
    }
  },
  
  updated(el, binding, vnode) {
    checkOwner(el, vnode);
  },
  
  unmounted(el) {
    if (el._ownerUnwatch) {
      el._ownerUnwatch();
      delete el._ownerUnwatch;
    }
  }
};

export default {
  can: canDirective,
  admin: adminDirective,
  owner: ownerDirective
};

