<template>
  <div
    class="l-card"
    :class="[
      highlight ? 'l-card--highlight' : null,
      bordered ? 'l-card--bordered' : null,
      disabled ? 'l-card--disabled' : null
    ]"
    :style="cardStyle"
    @click="onClick"
  >
    <div
      v-if="hasThumbSlot"
      class="l-card-thumbnail"
    >
      <!-- Thumbnail Slot -->
      <slot name="thumbnail" />
    </div>
    <header
      v-if="title || hasHeaderSlot"
      class="l-card-header"
    >
      <h3
        v-if="title"
        class="l-card-title"
      >
        {{ title }}
      </h3>
      <!-- Header Slot -->
      <div
        v-if="hasHeaderSlot"
        class="l-card-header-content"
      >
        <slot name="header" />
      </div>
    </header>
    <div
      v-if="hasDefaultSlot"
      class="l-card-content"
    >
      <!-- Default Slot -->
      <slot />
    </div>
    <div
      v-if="hasFooterSlot"
      class="l-card-footer"
    >
      <slot name="footer" />
    </div>
  </div>
</template>

<script>
export default {
  name: "LCard",
  props: {
    /**
     * The title of the card.
     */
    title: {
      type: String,
    },
    /**
     * The font size of the title.
     */
    titleSize: {
      type: String,
      default: "xl",
      validator: function (value) {
        return (
          ["xs", "sm", "base", "md", "lg", "xl", "2xl", "3xl"].indexOf(
            value
          ) !== -1
        );
      },
    },
    /**
     * Highlight the card.
     */
    highlight: {
      type: Boolean,
      default: false,
    },
    /**
     * Disable the card.
     */
     disabled: {
      type: Boolean,
      default: false,
    },
    /**
     * Allow overflow of the card content.
     */
    allowOverflow: {
      type: Boolean,
      default: false,
    },
    /**
     * Add a border around the card.
     */
    bordered: {
      type: Boolean,
      default: false,
    },
    /**
     * The padding inside the card.
     */
    padding: {
      type: String,
      default: "4",
      validator: function (value) {
        return ["0", "2", "4", "6", "8"].indexOf(value) !== -1;
      },
    },
    /**
     * The type color of the card.
     */
    type: {
      type: String,
      default: "white",
      validator: function (value) {
        return (
          [
            "primary",
            "secondary",
            "tertiary",
            "success",
            "warning",
            "danger",
            "neutral",
            "white",
            "black",
            "admin"
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * The shade of the card background color.
     */
    shade: {
      type: String,
      default: "50",
      validator: function (value) {
        return (
          [
            "50",
            "100",
            "200",
            "300",
            "400",
            "500",
            "600",
            "700",
            "800",
            "900",
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * The type color of the card footer.
     */
    footerType: {
      type: String,
      default: "neutral",
      validator: function (value) {
        return (
          [
            "primary",
            "secondary",
            "tertiary",
            "success",
            "warning",
            "danger",
            "neutral",
            "white",
            "black",
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * The shade of the card footer color.
     */
    footerShade: {
      type: String,
      default: "100",
      validator: function (value) {
        return (
          [
            "50",
            "100",
            "200",
            "300",
            "400",
            "500",
            "600",
            "700",
            "800",
            "900",
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * Add a shadow to the card component
     */
    shadow: {
      type: String,
      default: "none",
      validator: function (value) {
        return (
          ["none", "sm", "base", "md", "lg", "xl", "2xl"].indexOf(value) !== -1
        );
      },
    },
    /**
     * The radius of the card.
     */
    radius: {
      type: String,
      default: "lg",
      validator: function (value) {
        return (
          [
            "none",
            "sm",
            "base",
            "md",
            "lg",
            "xl",
            "2xl",
            "3xl",
            "full",
          ].indexOf(value) !== -1
        );
      },
    },
  },
  computed: {
    cardpadding() {
      return `var(--spacing-${this.padding})`;
    },
    negCardPadding() {
      return `var(--spacing-neg-${this.padding})`;
    },
    cardShadow() {
      return `var(--shadow-${this.shadow})`;
    },
    cardTitleSize() {
      return `var(--sizing-${this.titleSize})`;
    },
    cardRadius() {
      return `var(--radius-${this.radius})`;
    },
    cardpaddingDiv() {
      return `var(--spacing-${
        Number(this.padding) > 4 ? Number(this.padding) / 2 : this.padding
      })`;
    },
    cardBG() {
      if (this.type === "white" || this.type === "black") {
        return `var(--${this.type})`;
      }
      return `var(--${this.type}-${this.shade})`;
    },
    footerBG() {
      if (this.footerType === "white" || this.footerType === "black") {
        return `var(--${this.footerType})`;
      }
      return `var(--${this.footerType}-${this.footerShade})`;
    },
    cardText() {
      if (this.type === "white") {
        return `var(--neutral-900)`;
      }
      if (this.type === "black") {
        return `var(--white)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--white)`;
      }
      return `var(--${this.type}-900)`;
    },
    cardTextMeta() {
      if (this.type === "white") {
        return `var(--neutral-600)`;
      }
      if (this.type === "black") {
        return `var(--neutral-200)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--${this.type}-50)`;
      }
      return `var(--${this.type}-600)`;
    },
    cardBorder() {
      if (this.type === "white") {
        return `var(--neutral-100)`;
      }
      if (this.type === "black") {
        return `var(--neutral-900)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--${this.type}-600)`;
      }
      return `var(--${this.type}-100)`;
    },
    cardHighlight() {
      if (this.type === "white" || this.type === "black") {
        return `var(--primary-500)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--${this.type}-300)`;
      }
      return `var(--${this.type}-500)`;
    },
    cardStyle() {
      return {
        "--card-padding": this.cardpadding,
        "--neg-card-padding": this.negCardPadding,
        "--card-padding-div": this.cardpaddingDiv,
        "--card-bg": this.cardBG,
        "--footer-bg": this.footerBG,
        "--card-text": this.cardText,
        "--card-text-meta": this.cardTextMeta,
        "--card-highlight": this.cardHighlight,
        "--card-border": this.cardBorder,
        "--card-shadow": this.cardShadow,
        "--card-title-size": this.cardTitleSize,
        "--card-overflow": this.allowOverflow ? "visible" : "hidden",
        "--card-radius": this.cardRadius,
      };
    },
    hasHeaderSlot() {
      return !!this.$slots.header;
    },
    hasDefaultSlot() {
      return !!this.$slots.default;
    },
    hasThumbSlot() {
      return !!this.$slots.thumbnail;
    },
    hasFooterSlot() {
      return !!this.$slots.footer;
    },
  },
  methods: {
    onClick() {
      this.$emit("click");
    },
  },
};
</script>
<style>
.l-card {
  display: flex;
  flex-direction: column;
  background-color: var(--card-bg);
  overflow: var(--card-overflow);
  border-radius: var(--card-radius);
  color: var(--card-text);
  border: 0px solid var(--card-border);
  box-shadow: var(--card-shadow);
  position: relative;
}
.l-card:focus {
  outline-color: var(--card-border);
  outline-width: var(--spacing-0-5);
  outline-offset: var(--spacing-px);
  outline-style: solid;
}
.l-card--bordered {
  border-color: var(--card-border);
  border-width: 1px;
}
.l-card--highlight {
  border-color: var(--card-highlight);
  border-width: 2px;
}
.l-card--disabled {
  filter: blur(1px);
  pointer-events: none;
  cursor: not-allowed;
}
.l-card-thumbnail {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.02);
}
.l-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--card-padding);
  padding-bottom: 0;
  gap: var(--card-padding-div);
  color: var(--card-text-meta);
  font-size: var(--sizing-sm);
  border-bottom: 0px solid var(--card-border);
}
.l-card-footer {
  background-color: var(--footer-bg);
  padding: var(--card-padding);
  border-bottom-right-radius: var(--card-radius);
  border-bottom-left-radius: var(--card-radius);
  position: sticky;
  bottom: 0;
  left: 0;
  margin-top: auto;
}
.l-card--bordered .l-card-header {
  padding: var(--card-padding-div) var(--card-padding);
  border-bottom-width: 1px;
}
.l-card-title {
  font-size: var(--card-title-size);
  color: var(--card-text);
  font-weight: 700;
}
.l-card-content {
  padding: var(--card-padding);
}
.l-card-meta {
  color: var(--card-text-meta);
}
</style>
