<script setup lang="ts">
import { computed, ref, watch, type Slot } from 'vue'
import { useAttrsWithDefaults } from '../../../composables/useAttrsWithDefaults'
import { useHasSlot } from '../../../composables/useHasSlots'
import FdsIcon from '../../FdsIcon/FdsIcon.vue'
import FdsSticker from '../../FdsSticker/FdsSticker.vue'
import type { FdsExpanderBlockProps } from './types'

defineOptions({
  inheritAttrs: false,
})

const props = withDefaults(defineProps<FdsExpanderBlockProps>(), {
  disabled: false,
  heading: undefined,
  open: false,
  icon: undefined,
  iconClass: undefined,
  stickerColor: undefined,
  stickerText: undefined,
  dataTestid: undefined,
})

const { id, attrs } = useAttrsWithDefaults(props)

const hasExtraRowSlot = useHasSlot('extra-row')

const emit = defineEmits<{
  (e: 'toggle'): void
}>()

const isOpen = ref(props.open)

const autoId = `fds-block-expander-${Math.random().toString(36).slice(2, 9)}`
const blockExpanderId = computed(() => id.value ?? autoId)

const buttonAttrs = computed(() => {
  const { class: _, id: __, ...rest } = attrs
  return {
    ...rest,
    id: blockExpanderId.value,
  }
})

const wrapperClass = computed(() => attrs.class)

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

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

const expanderClasses = computed(() => [
  'expander-root block w-full rounded-2xl mb-4 shadow-[0_4px_16px_0_rgba(59,130,246,0.2)] transition-colors',
  props.disabled && 'shadow-none border-2 border-gray-200 border-dashed',
])

const headerClasses = computed(() => [
  'flex w-full flex-col text-left  bg-white text-blue-600 rounded-2xl p-[calc(1rem-2px)] border-2 border-white transition-colors border-2 border-white hover:border-blue-500 active:bg-blue_t-100 active:border-white focus-visible:border-blue-500 focus-visible:border-dashed focus-visible:outline-0',
  props.disabled ? 'cursor-not-allowed hover:border-2 hover:border-transparent  active:bg-white' : 'cursor-pointer',
  isOpen.value ? 'rounded-b-none' : 'rounded-b-2xl',
])

const buttonRowClasses = computed(() => ['flex justify-between items-start w-full', hasExtraRowSlot.value ? '' : ''])

function handleToggle() {
  if (props.disabled) return
  isOpen.value = !isOpen.value
  emit('toggle')
}

defineSlots<{
  default?: Slot
  'extra-row'?: Slot
}>()
</script>

<template>
  <div :class="[expanderClasses, wrapperClass]" v-bind="rootAttrs">
    <button v-bind="buttonAttrs" type="button" :class="headerClasses" @click="handleToggle">
      <span :class="buttonRowClasses">
        <span class="leading-6 w-full flex justify-between gap-4">
          <span class="flex items-center" :class="{ 'inline-flex items-start': icon }">
            <span v-if="icon" class="flex items-center mr-4">
              <FdsIcon
                :name="icon"
                :size="24"
                class="fill-blue-500"
                :class="[{ 'fill-gray-500': disabled }, iconClass]"
              />
            </span>
            <span class="inline-flex items-center">
              <span class="font-bold font-heading text-lg leading-6" :class="{ 'text-gray-700': disabled }">
                {{ heading }}
              </span>
            </span>
          </span>
          <span class="flex items-center gap-2">
            <template v-if="stickerText && stickerColor">
              <FdsSticker :variant="stickerColor">
                {{ stickerText }}
              </FdsSticker>
            </template>
            <FdsIcon
              name="arrowDown"
              :size="24"
              class="transition-transform duration-200 fill-blue-500 min-w-6 min-h-6"
              :class="{ 'rotate-180': isOpen, 'fill-gray-500': disabled }"
            />
          </span>
        </span>
      </span>
      <span v-if="hasExtraRowSlot && !isOpen" class="w-full flex mt-2">
        <slot name="extra-row" />
      </span>
    </button>
    <div :aria-hidden="!isOpen" class="mb-0-last-child block px-4 pb-6 rounded-b-2xl bg-white" v-show="isOpen">
      <slot />
    </div>
  </div>
</template>
