<script lang="ts" setup>
import { twJoin, twMerge } from 'tailwind-merge'
import ACalendar from "#adata-ui/components/elements/calendar/ACalendar.vue";


interface Props {
  disabled?: boolean
  label?: string
  size?: 'sm' | 'md'
  error?: string
  required?: boolean
  type?: 'single-date' | 'range-date'
  locale?: 'ru' | 'en'
  color: 'blue' | 'red' | 'yellow' | 'gray' | 'green'
  mode: 'date' | 'time' | 'dateTime'
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  label: '',
  size: 'md',
  error: '',
  required: false,
  type: 'single-date',
  locale: 'ru',
  color: 'blue',
  mode: 'date'
})

const date = defineModel<Date>({
  default: new Date()
})

const range = defineModel<{
  value: {
    start: Date
    end: Date
  }
}>('range', {
  default: {
    start: new Date(),
    end: new Date(new Date().setDate(new Date().getDate() + 14))
  }
})

const uiConfig = {
  wrapper: 'transition duration-500 w-full',
  "input-wrapper": {
    base: 'relative inline-block w-full text-sm sm:min-w-full'
  },
  base: 'w-full border-0 rounded-md text-deepblue-900 dark:text-gray-200 hover:outline hover:outline-1 hover:outline-blue-700 hover:dark:outline-blue-500 focus:outline focus:outline-blue-700 focus:dark:outline-blue-500 mt-0',
  size: {
    sm: 'h-8 px-4 py-1.5 sm',
    md: 'h-10 px-4 pb-1.5 pt-[18px] md'
  },
  color: 'bg-deepblue-900 bg-opacity-5 dark:bg-gray-200 dark:bg-opacity-5',
  error: 'outline outline-1 outline-red-500 focus:outline-0 focus:border-red-500 hover:border-red-500',
  label: {
    base: 'absolute left-4 top-[50%] d-flex text-gray-500 pointer-events-none transition-all ease duration-300 transform translate-y-[-50%] whitespace-nowrap',
    'move-label': '!left-10'
  },
  default: {
    size: 'md',
    color: 'gray'
  }
}

const optionsDate:Intl.DateTimeFormatOptions = {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
};

const optionsTime:Intl.DateTimeFormatOptions = {
  hour: 'numeric',
  minute: 'numeric'
};

const optionsDateTime:Intl.DateTimeFormatOptions = { ...optionsDate, ...optionsTime }

const getDateOptions = (value?: Date, mode = props.mode) => {
  let options

  switch (mode) {
    case 'time' : options = optionsTime; break
    case 'dateTime' : options = optionsDateTime; break
    default : options = optionsDate
  }

  return (value ? new Date(value) : new Date()).toLocaleString('ru-RU', options)
}

const isClearable = computed<boolean>(
  () => getDateOptions() !== getDateOptions(date.value)
)

const wrapperClass = uiConfig.wrapper

const inputWrapperClass = computed(() => twMerge(twJoin(
  uiConfig['input-wrapper'].base
)))

const inputClass = computed(() => twMerge(twJoin(
  uiConfig.base,
  props.color ?? uiConfig.color,
  uiConfig.size[props.size]
)))

const labelClass = computed(() => twMerge(twJoin(
  uiConfig.label.base
)))
</script>

<template>
  <ACalendar
    v-model:range="range"
    v-model="date"
    :type="type"
    :locale="locale"
    :color="color"
    :mode="mode"
  >
    <template #default="{ togglePopover, inputValue, inputEvents }">
      <div :class="wrapperClass">
        <div :class="inputWrapperClass">
          <input
            :id="label"
            ref="input"
            class="input"
            :class="inputClass"
            :value="type === 'single-date' ? `${inputValue}` : `${inputValue.start} - ${inputValue.end}`"
            v-on="inputEvents"
          >
          <label
            :for="label"
            :class="labelClass"
            class="label"
          >
            <span class="text">{{ label }}</span>
            <span
              v-if="required"
              class="text-red-600"
            > *</span>
          </label>

          <button
            v-if="isClearable"
            class="absolute top-1/2 right-12 pointer-events-click text-2xl transform translate-y-[-50%] hover:opacity-80 bg-deepblue-900 bg-opacity-10 dark:bg-gray-200 dark:bg-opacity-10 rounded-full p-1"
            type="button"
            @click="date = new Date()"
          >
            <a-icon-x-mark
              filled
              class="!mb-0 fill-gray-600 dark:fill-gray-300"
            />
          </button>
          <button
            class="absolute top-1/2 right-4 text-gray-500 fill-gray-500 pointer-events-click text-2xl transform translate-y-[-50%] hover:opacity-80 disabled:pointer-events-none"
            type="button"
            @click="() => togglePopover()"
          >
            <a-icon-calendar
              filled
              class="!mb-0"
            />
          </button>
        </div>
      </div>
    </template>
  </ACalendar>
</template>

<style scoped>
.input {
  &:focus ~ .label,
  &:not(:focus):valid ~ .label,
  &:-webkit-autofill ~ .label {
    font-size: 10px;
    transform: translateY(-17px);
  }

  &.sm {
    &:focus ~ .label,
    &:not(:focus):valid ~ .label,
    &:-webkit-autofill ~ .label {
      display: none;
    }
  }
}

.slide-in-enter-active {
  z-index: 0;
  opacity: 0;
  transform: translateY(-50%);
  transition: transform 0.5s;
}

.slide-in-enter-to {
  z-index: auto;
  opacity: 1;
  transform: translateY(0);
}

.slide-in-leave-active {
  opacity: 1;
  transform: translateY(0);
}

.slide-in-leave-to {
  opacity: 0;
  transform: translateY(-100%);
}
</style>
