<template>
  <div
    class="l-step"
    :class="['l-step--' + state]"
    :style="stepStyle"
  >
    <component
      :is="componentType"
      class="l-step-heading"
      :class="interactive ? 'l-step-heading--interactive' : null"
      :to="interactive && to ? to : null"
      @click="interactive && onClick()"
    >
      <div
        class="l-step-indicator"
        :class="indicatorState"
      >
        <l-icon
          v-if="state == 'complete'"
          size="3"
        >
          <icon-check />
        </l-icon>
        <l-icon
          v-else-if="state == 'error'"
          size="3"
        >
          <icon-warning />
        </l-icon>
        <span
          v-else
          class="l-step-count"
        />
      </div>
      <div
        v-if="hasIconSlot"
        class="l-step-indicator"
        :class="indicatorState"
      >
        <l-icon
          v-if="state == 'complete'"
          size="3"
        >
          <slot name="icon" />
        </l-icon>
      </div>
      <span
        v-if="title"
        class="l-step-title"
      >{{ title }}</span>
    </component>
    <div
      v-if="(hasDefaultSlot || subtitle) && showContent"
      class="l-step-content"
    >
      <p v-if="subtitle">
        {{ subtitle }}
      </p>
      <slot />
    </div>
  </div>
</template>

<script>
import LIcon from "../atoms/LIcon.vue";
import IconCheck from "../../icons/icon-check.vue";
import IconWarning from "../../icons/icon-warning.vue";
export default {
  name: "LStep",
  components: {
    IconWarning,
    LIcon,
    IconCheck,
  },
  props: {
    /**
     * Step title
     */
    title: {
      type: String,
    },
    /**
     * Subtitle for the step
     *
     * Can be used to help guide or inform the user
     */
    subtitle: {
      type: String,
    },
    /**
     * Show slot/subtitle
     *
     * Useful for hiding the step content if it's not needed
     */
    showContent: {
      type: Boolean,
      default: true,
    },
    /**
     * The state of the step.
     *
     * Possible values:
     * - `complete`
     * - `active`
     * - `inactive`
     */
    state: {
      type: String,
      default: "inactive",
      validator: function (value) {
        return (
          ["active", "inactive", "complete", "error"].indexOf(value) !== -1
        );
      },
    },
    /**
     * Make step clickable
     *
     * If true the click event will be emitted on the step and the `to` prop will be allowed
     */
    interactive: {
      type: Boolean,
      default: false,
    },
    /**
     * Url to navigate to when the step is clicked
     */
    to: {
      type: String,
    },
    /**
     * The type of the step color.
     */
    type: {
      type: String,
      default: "primary",
      validator: function (value) {
        return (
          [
            "primary",
            "secondary",
            "tertiary",
            "success",
            "danger",
            "warning",
            "neutral",
            "white",
            "black",
            "admin"
          ].indexOf(value) !== -1
        );
      },
    },
  },
  computed: {
    hasIconSlot() {
      return !!this.$slots.icon;
    },
    hasDefaultSlot() {
      return !!this.$slots.default;
    },
    stepStyle() {
      switch (this.state) {
        case "inactive":
          return { "--step-color": "var(--neutral-300)" };
        case "error":
          return { "--step-color": "var(--danger-500)" };
        case "active":
          if (this.type == "white" || this.type == "black") {
            return { "--step-color": "var(--" + this.type + ")" };
          }
          return { "--step-color": "var(--" + this.type + "-500)" };
        case "complete":
          if (this.type == "white" || this.type == "black") {
            return { "--step-color": "var(--" + this.type + ")" };
          }
          return { "--step-color": "var(--" + this.type + "-500)" };
      }
      return "";
    },
    indicatorState() {
      switch (this.state) {
        case "inactive":
          return "l-step-indicator--inactive";
        case "active":
          return "l-step-indicator--current";
        case "complete":
          return "l-step-indicator--complete";
        case "error":
          return "l-step-indicator--error";
      }
      return "";
    },
    componentType() {
      // if interactive and has to prop make nuxt link, else make it a button if only interactive else make it a div
      if (this.interactive && this.to) {
        return "n-link";
      } else if (this.interactive) {
        return "button";
      } else {
        return "div";
      }
    },
  },
  methods: {
    onClick() {
      this.$emit("click");
    },
  },
};
</script>
<style>
.l-step {
  color: var(--step-color);
  counter-increment: section;
  z-index: 40;
  display: flex;
  flex-direction: column;
}
.l-step-heading {
  display: inline-flex;
  align-items: center;
  font-size: var(--sizing-lg);
  font-weight: 700;
  text-align: left;
}
.l-step-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--spacing-8);
  height: var(--spacing-8);
  border-radius: var(--radius-full);
  border: 1px solid;
  background-color: var(--white);
  margin-right: var(--spacing-3);
  transition: all var(--duration-300) ease-in-out;
}
.l-step-indicator--complete {
  background-color: var(--step-color);
  color: var(--white);
}
.l-step-indicator--current {
  box-shadow: var(--shadow-md);
}
.l-step-heading--interactive {
  cursor: pointer;
}
.l-steps .l-step-heading--interactive:hover .l-step-indicator {
  transform: scale(1.2);
  background-color: var(--step-color);
  color: var(--white);
}
.l-step-count {
  position: relative;
  width: 100%;
  height: 100%;
}
.l-step-count::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  text-align: center;
  content: counter(section);
}
.l-step-title {
  font-size: var(--sizing-lg);
}
.l-step-content {
  padding: var(--spacing-2) var(--spacing-4);
  margin-left: var(--spacing-11);
  font-size: var(--sizing-sm);
  max-width: var(--spacing-64);
  border: 1px solid var(--neutral-100);
  border-radius: var(--radius-base);
  color: var(--neutral-400);
}
</style>
