import { forceUpdateElement, getOwnerInstance } from '@vizality/util/react';
import { waitForElement } from '@vizality/util/dom';
import { toKebabCase } from '@vizality/util/string';
import { patch, unpatch } from '@vizality/patcher';
import { getModule } from '@vizality/webpack';
import { Messages } from '@vizality/i18n';

export const labels = [ 'Chat', 'HeaderButton' ];

/**
 * Applies attributes to channel header buttons.
 * @module HeaderButton
 * @memberof Builtin.Attributes.Chat
 * @param {Addon} builtin The builtin's main class
 */
export default async builtin => {
  const { iconWrapper, clickable, iconBadge } = getModule('iconWrapper', 'toolbar');
  const instance = getOwnerInstance(await waitForElement(`.${iconWrapper}`));
  patch('vz-attributes-channel-header-buttons', instance?.__proto__, 'render', (_, res) => {
    try {
      if (!res.props?.children?.props?.className?.includes(iconWrapper, clickable)) {
        return res;
      }
      /**
       * We're using the aria-label prop to identify the button, because there's nothing
       * else we can use. The aria-label value changes based on the user's locale, so
       * not the best scenario, but it works.
       */
      const ariaLabel = res.props.children.props['aria-label'];
      if (!ariaLabel) {
        return;
      }
      /**
       * Try to match the aria-label to an i18n message string in order to get
       * a value that works for all locales.
       */
      let key = Object.keys(Messages).find(key => ariaLabel === Messages[key]);
      let unread;
      /**
       * Check if it's the pinned messages button so we can add a [vz-unread] attribute
       * for buttons with the unread pins badge.
       */
      if (key === 'PINNED_MESSAGES') {
        if (res.props.children.props.children[1]?.props?.className?.includes(iconBadge)) {
          unread = true;
        }
      }
      /**
       * If there's no key, it's likely because it's the channel umute/nmute button,
       * which uses formatting with the channel's name in it, so let's check for that.
       */
      if (!key) {
        const SelectedChannelId = getModule('getChannelId', 'getVoiceChannelId')?.getChannelId();
        const ChannelStore = getModule('getChannel')?.getChannel(SelectedChannelId);
        if (ariaLabel === Messages.CHANNEL_MUTE_LABEL?.format?.({ channelName: ChannelStore?.name })) {
          if (res.props.children.props['aria-checked'] === true) {
            key = 'channel-unmute';
          } else {
            key = 'channel-mute';
          }
        }
      }
      /**
       * If there's still no key, just return.
       */
      if (!key) {
        return;
      }
      /**
       * Manually set the attribute(s) to the ref.
       */
      res.props.children.ref = evt => {
        try {
          if (!evt) {
            return;
          }
          evt.setAttribute('vz-button', toKebabCase(key));
          if (unread === true) {
            evt.setAttribute('vz-unread', '');
          } else {
            evt.removeAttribute('vz-unread');
          }
        } catch (err) {
          return builtin.error(builtin._labels.concat(labels), err);
        }
      };
    } catch (err) {
      return builtin.error(builtin._labels.concat(labels), err);
    }
  });
  setImmediate(() => forceUpdateElement(`.${iconWrapper}`, true));
  return () => unpatch('vz-attributes-channel-header-buttons');
};
