import { watchEffect } from 'vue';
import type { Directive } from 'vue';
import { useAuthStore } from '@/store/modules/auth';
import { useObjectContextStore } from '@/store/modules/object-context';
import { type AuthDirectiveBindingValue, resolveAuthVisible } from './auth-shared';

type AuthDirectiveElement = HTMLElement & {
  authStopHandle?: (() => void) | null;
};

function toggleElementVisible(el: HTMLElement, visible: boolean) {
  el.style.display = visible ? '' : 'none';
}

function getVisible(bindingValue: string | AuthDirectiveBindingValue) {
  const authStore = useAuthStore();
  const objectContextStore = useObjectContextStore();

  return resolveAuthVisible(bindingValue, {
    globalButtonCodes: authStore.userInfo.buttons,
    objectButtonCodes: objectContextStore.buttonCodes
  });
}

function bindAuthEffect(el: AuthDirectiveElement, bindingValue: string | AuthDirectiveBindingValue) {
  el.authStopHandle?.();

  el.authStopHandle = watchEffect(() => {
    toggleElementVisible(el, getVisible(bindingValue));
  });
}

export const authDirective: Directive<AuthDirectiveElement, string | AuthDirectiveBindingValue> = {
  mounted(el, binding) {
    bindAuthEffect(el, binding.value);
  },
  updated(el, binding) {
    bindAuthEffect(el, binding.value);
  },
  unmounted(el) {
    el.authStopHandle?.();
    el.authStopHandle = null;
  }
};
