<script setup lang="ts">
import { computed, useCssModule, useAttrs, CSSProperties } from "vue";

export type TagVariant =
  | "h1-semibold"
  | "h2-regular"
  | "h2-semibold"
  | "title1-semibold"
  | "title1-regular"
  | "title2-semibold"
  | "title2-regular"
  | "body-regular"
  | "body-semibold"
  | "copy-medium"
  | "cta-semibold";

type ColorVariant = "primary" | "secondary";

interface Props {
  variant?: TagVariant;
  component?: string;
  className?: string;
  style?: CSSProperties;
  color?: string;
  id?: string;
  ariaHidden?: boolean;
  tabIndex?: number;
}

const props = withDefaults(defineProps<Props>(), {
  variant: "body-regular",
  component: undefined,
  className: "",
  style: undefined,
  color: undefined,
  id: undefined,
  ariaHidden: undefined,
  tabIndex: undefined,
});

const attrs = useAttrs();
const styles = useCssModule();

// Mapping between variants and default HTML tags
const variantsMapping: Record<TagVariant, string> = {
  "h1-semibold": "h1",
  "h2-regular": "h2",
  "h2-semibold": "h2",
  "title1-semibold": "h3",
  "title1-regular": "h4",
  "title2-semibold": "h5",
  "title2-regular": "h6",
  "body-semibold": "p",
  "body-regular": "p",
  "copy-medium": "p",
  "cta-semibold": "p",
};

// Color mapping for predefined colors
const colorsMapping: Record<ColorVariant, string> = {
  primary: "var(--cc-primary-color)",
  secondary: "var(--cc-secondary-color)",
};

// Determine which HTML element to render
const componentTag = computed(() => {
  return props.component ?? variantsMapping[props.variant];
});

// Compute the color value
const typographyColor = computed(() => {
  if (!props.color) return undefined;
  return colorsMapping[props.color as ColorVariant] ?? props.color;
});

// Compute CSS classes
const componentClasses = computed(() => {
  const classes = [styles[props.variant]];
  if (props.className) classes.push(props.className);
  if (props.color) classes.push(props.color);
  return classes.filter(Boolean).join(" ");
});

// Compute merged styles
const componentStyle = computed(() => {
  const mergedStyle: CSSProperties = { ...props.style };
  if (typographyColor.value) {
    mergedStyle.color = typographyColor.value;
  }
  return mergedStyle;
});
</script>

<template>
  <component
    :is="componentTag"
    :id="id"
    :class="componentClasses"
    :style="componentStyle"
    :aria-hidden="ariaHidden"
    :tabIndex="tabIndex"
    v-bind="attrs"
  >
    <slot />
  </component>
</template>

<style module>
.h1-semibold {
  font-size: calc(var(--cc-font-size, 14px) * 2.4286); /* 34px at 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 2.9143); /* 40.8px at 14px base */
}

.h2-regular {
  font-size: calc(var(--cc-font-size, 14px) * 1.2857); /* 18px at 14px base */
  font-style: normal;
  font-weight: 400;
  line-height: calc(var(--cc-font-size, 14px) * 1.6714); /* 23.4px at 14px base */
}

.h2-semibold {
  font-size: calc(var(--cc-font-size, 14px) * 1.2857); /* 18px at 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 1.6714); /* 23.4px at 14px base */
}

.title1-regular {
  font-size: calc(var(--cc-font-size, 14px) * 1.1429); /* 16px at 14px base */
  font-style: normal;
  font-weight: 400;
  line-height: calc(var(--cc-font-size, 14px) * 1.6); /* 22.4px at 14px base */
}

.title1-semibold {
  font-size: calc(var(--cc-font-size, 14px) * 1.1429); /* 16px at 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 1.6); /* 22.4px at 14px base */
}

.title2-regular {
  font-size: calc(var(--cc-font-size, 14px) * 0.8571); /* 12px at 14px base */
  font-style: normal;
  font-weight: 400;
  line-height: calc(var(--cc-font-size, 14px) * 1.2); /* 16.8px at 14px base */
}

.title2-semibold {
  font-size: calc(var(--cc-font-size, 14px) * 0.8571); /* 12px at 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 1.1143); /* 15.6px at 14px base */
}

.body-regular {
  font-size: var(--cc-font-size, 14px); /* 14px base */
  font-style: normal;
  font-weight: 400;
  line-height: calc(var(--cc-font-size, 14px) * 1.4); /* 19.6px at 14px base */
}

.body-semibold {
  font-size: var(--cc-font-size, 14px); /* 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 1.3); /* 18.2px at 14px base */
}

.copy-medium {
  font-size: calc(var(--cc-font-size, 14px) * 0.8571); /* 12px at 14px base */
  font-style: normal;
  font-weight: 500;
  line-height: calc(var(--cc-font-size, 14px) * 1.2); /* 16.8px at 14px base */
}

.cta-semibold {
  font-size: var(--cc-font-size, 14px); /* 14px base */
  font-style: normal;
  font-weight: 600;
  line-height: calc(var(--cc-font-size, 14px) * 1.3); /* 18.2px at 14px base */
}
</style>
