import { type Moment } from 'moment'
import {
  defineComponent, type PropType, ref, type Ref,
} from 'vue'
import useClickOutside from '../../../../composables/use-click-outside'
import MultipleCalendar from '../../calendars/multiple-calendar/multiple-calendar'

import './multiple-calendar-input.scss'

/**
 * Календарь с возможностью выбора нескольких дат.
 * <p>
 *   <a href="https://www.figma.com/file/Q4Z4CnFx4i0qhD5fbgnPpf/%F0%9F%92%BB-%D0%94%D0%B8%D0%B7%D0%B0%D0%B9%D0%BD-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-ARK-SPACE?type=design&node-id=12904%3A160768&mode=dev" target="_blank">Дизайн</a>
 * </p>
 */
export default defineComponent({
  props: {
    /**
     * Определяет, активен ли компонент или отключен.
     */
    isDisabled: { type: Boolean, default: false },
    /**
     * Показать или скрыть лейбл-название над инпутом.
     */
    isShowLabel: { type: Boolean, default: true },
    /**
     * Текст лейбла (названия) над инпутом.
     */
    label: { type: String, default: '' },
    /**
     * Текст, который будет отображаться в случае отсутствия выбранных дат.
     */
    placeholder: { type: String, default: '__.__.____' },
    /**
     * Массив строк, представляющих ошибки, связанные с компонентом.
     */
    errors: { type: Array as PropType<string[]>, default: () => [] },
    /**
     * Массив дат, представляющих выбранные дни.
     */
    days: { type: Array as PropType<Moment[]>, required: true },
    /**
     * Функция, которая вызывается при изменении выбранных дней.
     */
    onValueChange: { type: Function as PropType<(days: Moment[]) => void>, required: true },
    /**
     * Максимальное количество отображаемых выбранных дат в заголовке компонента.
     */
    maxChipsShow: { type: Number, default: 2 },
  },
  setup(props) {
    const isShowMultipleCalendar = ref(false)
    const calendar: Ref<HTMLDivElement | null> = ref(null)

    const isShowDropdown = ref(false)

    const onShowDropdown = () => {
      if (props.isDisabled || props.days.length < props.maxChipsShow || isShowMultipleCalendar.value) {
        return
      }

      isShowDropdown.value = !isShowDropdown.value
    }

    const onCloseDropdown = () => {
      if (isShowDropdown.value) isShowDropdown.value = false
    }

    const changeFlagShowMultipleCalendar = () => {
      if (props.isDisabled) return
      isShowMultipleCalendar.value = !isShowMultipleCalendar.value
      if (isShowMultipleCalendar.value) isShowDropdown.value = false
    }

    const clear = (e: MouseEvent) => {
      e.stopPropagation()

      if (props.onValueChange) props.onValueChange([])
    }

    const clearOneDate = (clearDate: Moment) => {
      if (props.onValueChange) props.onValueChange(props.days.filter((el) => el !== clearDate))
    }

    useClickOutside(calendar, () => {
      isShowMultipleCalendar.value = false
    })

    const rednerChips = (d: Moment) => (
      <div class='ark-ui-multiple-calendar-input-head-chips'>
        {d.format('DD.MM.YYYY')}
        {!props.isDisabled && (
          <div
            onClick={(e) => {
              e.stopPropagation()
              clearOneDate(d)
            }}
            class='ark-ui-multiple-calendar-input-head-chips-clear'
          />
        )}
      </div>
    )

    return () => (
      <div
        class={`ark-ui-multiple-calendar-input ${props.isDisabled ? 'disabled' : ''} ${props.errors.length ? 'invalid' : ''}`}
        onMouseleave={onCloseDropdown}
      >
        {props.label && props.isShowLabel && <div class='ark-ui-multiple-calendar-input-label'>{props.label}</div>}

        <div ref={calendar} class='ark-ui-multiple-calendar-input-head' onClick={changeFlagShowMultipleCalendar}>
          <div class='ark-ui-multiple-calendar-input-head-chips-container'>
            {props.days.length !== 0
              ? props.days.slice(0, props.maxChipsShow).map(rednerChips)
              : <div class="ark-ui-period-calendar-input-head-placeholder">{props.placeholder}</div>
            }
            {props.days.length > props.maxChipsShow && (
              <div class='ark-ui-multiple-calendar-input-head-chips' onMouseenter={onShowDropdown}>
                +{props.days.length - props.maxChipsShow}
              </div>
            )}
          </div>
          {props.days.length > 0 && !props.isDisabled ? (
            <div onClick={clear} class='ark-ui-multiple-calendar-input-head-chips-clear'/>
          ) : <div class='ark-ui-multiple-calendar-input-icon' />}
        </div>

        {!props.isDisabled && props.errors.map((error) => <div class='ark-ui-multiple-calendar-input-error'>{error}</div>)}

        {isShowMultipleCalendar.value && (
          <div
            class='ark-ui-multiple-calendar-input-body-container'
            onClick={(e) => {
              e.stopPropagation()
            }}
          >
            <MultipleCalendar
              class='ark-ui-multiple-calendar-input-expand-calendar'
              days={props.days}
              onSetDay={(v) => {
                if (props.onValueChange) props.onValueChange(v)
              }}
              disablePastDates={true}
            />
          </div>
        )}

        {isShowDropdown.value && (
          <div class='ark-ui-multiple-calendar-input-dropdown-wrapper'>
            <div class='ark-ui-multiple-calendar-input-dropdown'>{
              props.days.slice(props.maxChipsShow, props.days.length).map(rednerChips)
            }</div>
          </div>
        )}
      </div>
    )
  },
})
