<script setup lang="ts">
import { computed, ref, watch, type Slot } from 'vue'
import FdsButtonMinor from '../Buttons/FdsButtonMinor/FdsButtonMinor.vue'
import type { FdsTruncatedTextProps } from './types'

const props = withDefaults(defineProps<FdsTruncatedTextProps>(), {
  open: false,
  btnExpand: 'Visa mer',
  btnCollapse: 'Visa mindre',
  dataTestid: undefined,
  content: undefined,
  previewLength: 150,
  minHiddenChars: 25,
})

const emit = defineEmits<{
  (e: 'toggleHandler', data: { open: boolean }): void
}>()

const isOpen = ref(props.open)
const hasContent = computed(() => props.content !== undefined)

const isTruncated = computed(() => {
  const description = props.content ?? ''
  const hiddenChars = description.length - props.previewLength
  return hiddenChars >= props.minHiddenChars
})

const truncatedText = computed(() => {
  const description = props.content ?? ''
  if (isOpen.value || !isTruncated.value) return description
  return `${description.slice(0, props.previewLength).trimEnd()}...`
})

const toggleComponent = () => {
  isOpen.value = !isOpen.value
  emit('toggleHandler', { open: isOpen.value })
}

watch(
  () => props.open,
  (newValue) => {
    isOpen.value = newValue
  },
)

const rootAttrs = computed(() => {
  const attrs: Record<string, string> = {}
  if (props.dataTestid) {
    attrs['data-testid'] = props.dataTestid
  }
  return attrs
})

defineSlots<{
  default?: Slot
}>()
</script>

<template>
  <div class="block mb-4" v-bind="rootAttrs">
    <template v-if="hasContent">
      <span>{{ truncatedText }}</span>
      <FdsButtonMinor
        v-if="isTruncated"
        :icon="isOpen ? 'arrowUp' : 'arrowDown'"
        iconPos="right"
        :text="isOpen ? btnCollapse : btnExpand"
        @click="toggleComponent"
        class="inline! ml-2"
      />
    </template>
    <div v-else>
      <slot />
    </div>
  </div>
</template>
