<template>
  <component
    :is="linkComponentName"
    v-bind="linkComponentProps"
    :href="router ? null : href && !disabled ? href : null"
    class="mc-link"
    :class="classObject"
    @click="onClick"
  >
    <MIcon
      v-if="icon && iconPosition === 'left'"
      class="mc-link__icon"
      :class="classObjectIcon"
      :name="icon"
    />
    <!-- @slot Use this slot to insert the textual content of the Link -->
    <slot />
    <MIcon
      v-if="icon && iconPosition === 'right'"
      class="mc-link__icon"
      :class="classObjectIcon"
      :name="icon"
    />
  </component>
</template>

<script>
import { checkThemeValue } from '../../utils/theme.validator';
import {
  responsiveModifierValidators,
  responsiveModifiers,
} from '../../utils/mozaicClasses';
import MIcon from '../icon/MIcon.vue';

/**
 * > A link is a component used exclusively to navigate to internal or external webpages or to anchors in the current page.
 *
 * The `MLink` component is the **Vue.js** implementation of the **Link** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/links/).
 */
export default {
  name: 'MLink',
  components: {
    MIcon,
  },
  props: {
    /**
     * The value of the `href` attribute of the Link
     */
    href: {
      type: String,
      default: '#',
    },
    /**
     * The theme of the Link. Can be used for contextual variations.
     * @see [Contextual links](https://mozaic.adeo.cloud/components/links/#contextual-links)
     */
    theme: {
      type: String,
      default: null,
      validator: (value) => checkThemeValue(value),
    },
    /**
     * Link size
     * @values s, m
     */
    size: {
      type: String,
      default: 'm',
      validator: (value) => responsiveModifierValidators(value, ['s', 'm']),
    },
    /**
     * An object allowing to use the component as a routerLink and to pass it the associated prop
     * @type {{ name: 'router-link', props: { to: { name: 'MyPage' } } }}
     */
    router: {
      type: Object,
      default: null,
    },
    /**
     * Experimental solution waiting on this issue https://github.com/adeo/mozaic-vue/issues/52
     * @deprecated
     * @ignore
     * */
    responsiveSizeModifiers: {
      type: Array,
      default: null,
      validator: (array) =>
        array.every((e) =>
          responsiveModifierValidators(e, [
            's@from-m',
            's@from-l',
            's@from-xl',
            's@from-xxl',
            'm@from-m',
            'm@from-l',
            'm@from-xl',
            'm@from-xxl',
          ]),
        ),
    },
    /**
     * The name of the icon to add to the Link
     * @see [Available icons](https://mozaic.adeo.cloud/foundations/icons/)
     */
    icon: {
      type: String,
      default: null,
    },
    /**
     * Define the icon position
     * @values left, right
     */
    iconPosition: {
      type: String,
      default: 'left',
      validator: (value) => ['left', 'right'].includes(value),
    },
    /**
     * Allows to disabled the Link
     */
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['click'],
  computed: {
    classObject() {
      const classes = [];

      if (this.theme) {
        classes.push(`mc-link--${this.theme}`);
      }

      if (this.size) {
        responsiveModifiers('mc-link', this.size, classes);
      }

      if (this.disabled) {
        classes.push('is-disabled');
      }

      return classes;
    },
    classObjectIcon() {
      return {
        [`mc-link__icon--${this.iconPosition}`]: this.iconPosition,
      };
    },
    linkComponentName() {
      const isLinkValid = this.href && !this.disabled;
      const routerComponent = this.router?.name ?? null;
      const defaultComponent = isLinkValid ? 'a' : 'span';

      return routerComponent ?? defaultComponent;
    },
    linkComponentProps() {
      return this.router?.props ?? {};
    },
  },
  methods: {
    onClick(event) {
      if (!this.disabled) {
        /**
         * Triggers on click to the Link
         */
        this.$emit('click', event);
      }
    },
  },
};
</script>

<style scoped lang="scss">
@import 'settings-tools/all-settings';
@import 'components/c.links';
</style>
