<template>
  <div
    class="am-collapse-item"
    :class="[
      {'am-collapse-item-no-button': !partsVisibility || props.side},
      {'am-collapse-item-no-border': props.borderless},
      {'am-collapse-item__arrow' : props.side && partsVisibility},
      {'am-collapse-item__open': contentVisibility}
    ]"
    :style="cssVars"
  >
    <div
      class="am-collapse-item__heading"
      :class="[
        {'am-collapse-item__heading-active' : contentVisibility},
        {'am-collapse-item__heading-side' : contentVisibility && props.side},
        props.headingClass
      ]"
      :tabindex="props.side ? 0 : undefined"
      @click="onHeadingClick"
      @keydown.enter.prevent="onHeadingKeydown"
      @keydown.space.prevent="onHeadingKeydown"
    >
      <div v-if="props.side && partsVisibility && props.arrowPosition === 'left'" class="am-collapse-item__trigger am-collapse-item__trigger-side am-collapse-item__trigger-side--left">
        <slot name="icon-start" class="am-collapse-item__trigger-start"></slot>
        <span class="am-icon-arrow-down" :class="{'am-rotate-180': contentVisibility}"></span>
        <slot name="icon-end"></slot>
      </div>
      <slot name="heading"></slot>
      <div v-if="props.side && partsVisibility && props.arrowPosition !== 'left'" class="am-collapse-item__trigger am-collapse-item__trigger-side">
        <slot name="icon-start" class="am-collapse-item__trigger-start"></slot>
        <span class="am-icon-arrow-down" :class="{'am-rotate-180': contentVisibility}"></span>
        <slot name="icon-end"></slot>
      </div>
      <slot name="icon-below"></slot>
    </div>

    <template v-if="partsVisibility && !contentClosed">
      <div
        ref="collapseContent"
        class="am-collapse-item__content"
        :class="[
          {'am-collapse-item__content-no-border' : !props.side},
          contentVisibility ? 'am-collapse-item__content-open' : 'am-collapse-item__content-close',
          contentClosing ? 'am-collapse-item__content-closing' : ''
        ]"
        tabindex="-1"
      >
        <slot></slot>
      </div>
    </template>
    <div
      v-if="partsVisibility && !props.side"
      class="am-collapse-item__trigger"
      :tabindex="partsVisibility && !props.side ? 0 : -1"
      @click="onTriggerClick"
      @keydown.enter.prevent="onTriggerKeydown"
      @keydown.space.prevent="onTriggerKeydown"
    >
      <span class="am-collapse-item__trigger-label">
        <slot v-if="!contentVisibility && !props.buttonClosed.length" name="button-closed"></slot>
        <template v-if="!contentVisibility && props.buttonClosed.length">
          {{ props.buttonClosed }}
        </template>
        <slot v-if="contentVisibility && !props.buttonOpened.length" name="button-opened"></slot>
        <template v-if="contentVisibility && props.buttonOpened.length">
          {{ props.buttonOpened }}
        </template>
      </span>
      <span class="am-icon-arrow-down" :class="{'am-rotate-180': contentVisibility}"></span>
    </div>
  </div>
</template>

<script setup>
// * Import from Vue
import {
  inject,
  ref,
  reactive,
  computed,
  nextTick,
  useSlots
} from 'vue';

// * Composables
import { useColorTransparency } from "../../../assets/js/common/colorManipulation";

/**
 * Component Props
 */
let props = defineProps({
  buttonOpened: {
    type: String,
    default: ''
  },
  buttonClosed: {
    type: String,
    default: ''
  },
  side: {
    type: Boolean,
    default: false
  },
  borderless: {
    type: Boolean,
    default: false
  },
  type: {
    type: String,
    default: ''
  },
  delay: {
    type: Number,
    default: 500
  },
  collapsable: {
    type: Boolean,
    default: true
  },
  headingClass: {
    type: String,
    default: ''
  },
  arrowPosition: {
    type: String,
    default: 'right'
  }
})

/**
 * Component Emits
 * @type {EmitFn<(string)[]>}
 */
const emits = defineEmits(['collapseOpen', 'collapseClose', 'collapseClicked'])

// * Template slots
let slots = useSlots()

let partsVisibility = computed(() => {
  return slots.default().length && slots.default()[0].props !== null
})

const keyboardToggleHandledKey = '__amCollapseKeyboardToggleHandled'

function eventHandledByKeyboard(event) {
  return !!(event && event[keyboardToggleHandledKey])
}

function markEventHandledByKeyboard(event) {
  if (event) {
    event[keyboardToggleHandledKey] = true
  }
}

// * Card Expand variable
let contentVisibility = ref(false)
let contentClosing = ref(false)
let contentClosed = ref(true)
let collapseContent = ref(null)
let collapseHeight = reactive({
  h: '0px'
})

function closingCollapse () {
  contentClosing.value = true
  setTimeout(() => {
    contentClosing.value = false
    contentClosed.value = true
  }, 480)
}

function toggleContentHeading () {
  if (props.side && props.collapsable) {
    toggleContent()
  }
}

// * Card Expand Function
function toggleContentButton () {
  if (!props.side && props.collapsable) {
    toggleContent()
  }
}

function onHeadingClick(event) {
  if (eventHandledByKeyboard(event)) {
    return
  }

  toggleContentHeading()
}

function onHeadingKeydown(event) {
  markEventHandledByKeyboard(event)
  toggleContentHeading()
}

function onTriggerClick(event) {
  if (eventHandledByKeyboard(event)) {
    return
  }

  toggleContentButton()
}

function onTriggerKeydown(event) {
  markEventHandledByKeyboard(event)
  toggleContentButton()
}

// * Card Expand Function
function toggleContent () {
  emits('collapseClicked')
  if (partsVisibility.value) {
    setTimeout(() => {
      if (collapseContent.value) {
        collapseHeight.h = `${collapseContent.value.offsetHeight}px`
      }
      if (contentVisibility.value) closingCollapse()
      contentVisibility.value = !contentVisibility.value
      if (contentVisibility.value) {
        emits('collapseOpen')
        contentClosed.value = false
      }
      if (!contentVisibility.value) emits('collapseClose')
    }, props.delay)
  }
}

function closingFromParent () {
  if (contentVisibility.value) closingCollapse()
  contentVisibility.value = false
}

function openingFromParent () {
  contentVisibility.value = true
  contentClosed.value = false
}

function focusContent () {
  nextTick(() => {
    if (collapseContent.value) {
      collapseContent.value.focus()
    }
  })
}

defineExpose({
  closingFromParent,
  openingFromParent,
  focusContent,
  contentVisibility
})

// * Colors
let amColors = inject('amColors', ref({
  colorPrimary: '#1246D6',
  colorSuccess: '#019719',
  colorError: '#B4190F',
  colorWarning: '#CCA20C',
  colorMainBgr: '#FFFFFF',
  colorMainHeadingText: '#33434C',
  colorMainText: '#1A2C37',
  colorSbBgr: '#17295A',
  colorSbText: '#FFFFFF',
  colorInpBgr: '#FFFFFF',
  colorInpBorder: '#D1D5D7',
  colorInpText: '#1A2C37',
  colorInpPlaceHolder: '#1A2C37',
  colorDropBgr: '#FFFFFF',
  colorDropBorder: '#D1D5D7',
  colorDropText: '#0E1920',
  colorBtnPrim: '#265CF2',
  colorBtnPrimText: '#FFFFFF',
  colorBtnSec: '#1A2C37',
  colorBtnSecText: '#FFFFFF',
}))
let cssVars = computed(() => {
  return {
    '--am-c-collapse-text-op80': useColorTransparency(amColors.value.colorMainText, 0.8),
    '--am-c-collapse-text-op10': useColorTransparency(amColors.value.colorMainText, 0.1),
    '--am-delay-collapse': `${props.delay}ms`,
  }
})
</script>

<style lang="scss">
$collapseContentHeight: v-bind('collapseHeight.h');

@keyframes am-animation-collapse-open {
  0%{height: 0;}
  100%{height: $collapseContentHeight;}
}

@keyframes am-animation-collapse-close {
  0%{height: $collapseContentHeight;}
  100%{height: 0;}
}

@mixin am-collapse-item-block {
  // Collapse card
  // am  -- amelia
  // c - color
  // v - visible
  .am-collapse-item {
    --am-c-collapse-border: var(--am-c-inp-border);
    --am-c-collapse-text: var(--am-c-main-text);
    --am-combo-collapse-border: 1px solid var(--am-c-inp-border);
    --am-pointer-collapse: unset;
    position: relative;
    margin: 8px 0;
    overflow: hidden;

    &-no-button {
      .am-collapse-item__heading {
        border-radius: 8px;
        &-side {
          border-radius: 8px 8px 0 0;
          border-bottom: 0;
        }
      }
    }

    &-no-border {
      --am-combo-collapse-border: none;
    }

    &__arrow {
      --am-pointer-collapse: pointer;
    }

    * {
      font-family: var(--am-font-family);
      box-sizing: border-box;
    }

    // Collapse header
    &__heading {
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-radius: 8px 8px 0 0;
      padding: 16px;
      border: var(--am-combo-collapse-border);
      cursor: var(--am-pointer-collapse);
      transition-delay: var(--am-delay-collapse);

      &:focus {
        border-color: var(--am-c-collapse-text-op80);

        & + .am-collapse-item__content {
          border-color: var(--am-c-collapse-text-op80);
        }
      }

      &-side {
        transition-delay: 0ms;
      }
    }

    // Collapse card content
    &__content {
      display: flex;
      font-size: 14px;
      font-weight: 400;
      line-height: 1.4285;
      color: var(--am-c-collapse-text-op80);
      border: var(--am-combo-collapse-border);
      border-radius: 0 0 8px 8px;
      overflow: hidden;
      position: absolute;
      opacity: 0;
      z-index: -1;

      & > * {
        padding: 16px;
      }

      &-no-border {
        border-radius: 0;
        border-top: 0;
        border-bottom: 0;
      }

      &-open {
        position: relative;
        opacity: 1;
        z-index: 100;
        animation: 500ms ease-in-out am-animation-collapse-open;
      }

      &-closing {
        position: relative;
        opacity: 1;
        z-index: 100;
      }

      &-close {
        animation: 500ms ease-in-out am-animation-collapse-close;
      }
    }

    // Collapse trigger button
    &__trigger {
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 13px;
      line-height: 1.5385;
      color: var(--am-c-collapse-text);
      padding: 8px 16px;
      border: var(--am-combo-collapse-border);
      border-top: none;
      border-radius: 0 0 8px 8px;
      cursor: pointer;

      &:focus {
        background-color: var(--am-c-collapse-text-op10);

        .am-collapse-item__trigger-label {
          color: var(--am-c-collapse-text-op80);
        }
      }

      &-side {
        border: none;

        &--left {
          margin-right: 8px;
          flex: 0 0 auto;
        }
      }

      &-label {
        font-size: 13px;
        line-height: 1.5385;
        color: var(--am-c-collapse-text);
      }

      .am-icon-arrow-down {
        font-size: 16px;
        line-height: 1.4;
        color: var(--am-c-collapse-text);
        transition: all 0.3s ease-in-out;

        &.am-rotate-180 {
          transform: rotate(180deg);
        }
      }
    }
  }
}

// public
.amelia-v2-booking #amelia-container {
  @include am-collapse-item-block;
}

// admin
#amelia-app-backend-new {
  @include am-collapse-item-block;
}

// modal popup
.am-dialog-popup {
  @include am-collapse-item-block;
}
</style>
