<template>
  <div class="loyalty-suite-datepicker" ref="datepickerToggle" @click="openPicker">
    <span v-if="formattedDate" class="loyalty-suite-datepicker__text">{{ formattedDate }}</span>
    <span v-else class="loyalty-suite-datepicker__text">{{ $t('selectPeriod') }}</span>

    <div v-if="formattedDate" class="loyalty-suite-datepicker__clear">
      <span
        class="loyalty-suite-material-icons loyalty-suite-material-icons_pointer"
        @click.stop="clearDate"
      >
        close
      </span>
    </div>

    <div class="loyalty-suite-datepicker__icon">
      <span
        class="loyalty-suite-material-icons loyalty-suite-material-icons_pointer"
        data-datepicker="period"
      >
        event
      </span>
    </div>

    <div
      v-if="datePickerVisible"
      ref="datepickerPopup"
      @click.self="handlePopoverClick"
      class="loyalty-suite-popover"
    >
      <q-date
        class="loyalty-suite-date"
        v-model="date"
        :mask="dateMask"
        :locale="datePickerLocale"
        :first-day-of-week="wpStartOfWeek"
        range
        @update:model-value="updateFormattedDate"
      >
        <div class="loyalty-suite-datepicker__close">
          <span @click="closeDatePicker" class="loyalty-suite-button">
            {{ $t('close') }}
          </span>
        </div>
      </q-date>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, onBeforeUnmount, watch } from 'vue';
import { useI18n } from 'vue-i18n';

export default defineComponent({
  name: 'Datepicker',
  props: {
    modelValue: {
      type: [String, Object],
      required: true,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const { t } = useI18n();

    const date = ref<any>(props.modelValue);
    const formattedDate = ref('');
    const datePickerVisible = ref(false);
    const datepickerPopup = ref<HTMLElement | null>(null);
    const datepickerToggle = ref<HTMLElement | null>(null);
    const isMobileOrTablet = ref(window.innerWidth <= 1024);
    const wpStartOfWeek = window.loyalty_suite_account_data?.startOfWeek ?? 1;
    const wpDateFormat = window.loyalty_suite_account_data?.dateFormat || 'Y-m-d';

    const openPicker = (): void => {
      datePickerVisible.value = true;
    };

    const closeDatePicker = (): void => {
      datePickerVisible.value = false;
    };

    const clearDate = (): void => {
      date.value = '';
      formattedDate.value = '';
      emit('update:modelValue', '');
      closeDatePicker();
    };

    const handleClickOutside = (event: MouseEvent): void => {
      const target = event.target as Node;
      if (
        datePickerVisible.value &&
        datepickerPopup.value &&
        datepickerToggle.value &&
        !datepickerPopup.value.contains(target) &&
        !datepickerToggle.value.contains(target)
      ) {
        closeDatePicker();
      }
    };

    const handlePopoverClick = (): void => {
      if (isMobileOrTablet.value) {
        closeDatePicker();
      }
    };

    const updateDeviceType = (): void => {
      isMobileOrTablet.value = window.innerWidth <= 1024;
    };

    watch([datePickerVisible, isMobileOrTablet], ([visible, isMobile]) => {
      if (isMobile) {
        document.body.classList.toggle('loyalty-suite-no-scroll', visible);
      }
    });

    // Маска для q-date (всегда YYYY-MM-DD)
    const dateMask = 'YYYY-MM-DD';

    const datePickerLocale = {
      days: [
        t('Sunday'),
        t('Monday'),
        t('Tuesday'),
        t('Wednesday'),
        t('Thursday'),
        t('Friday'),
        t('Saturday'),
      ],
      daysShort: [t('Sun'), t('Mon'), t('Tue'), t('Wed'), t('Thu'), t('Fri'), t('Sat')],
      months: [
        t('January'),
        t('February'),
        t('March'),
        t('April'),
        t('May'),
        t('June'),
        t('July'),
        t('August'),
        t('September'),
        t('October'),
        t('November'),
        t('December'),
      ],
      monthsShort: [
        t('Jan'),
        t('Feb'),
        t('Mar'),
        t('Apr'),
        t('MayShort'),
        t('Jun'),
        t('Jul'),
        t('Aug'),
        t('Sep'),
        t('Oct'),
        t('Nov'),
        t('Dec'),
      ],
    };

    const normalizeYmd = (value: string | null | undefined): string => {
      if (!value) return '';
      const trimmed = String(value).trim();
      const match = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})/);
      if (!match) return '';
      const [, y, m, d] = match;
      return `${y}-${m}-${d}`;
    };

    const formatSingleDate = (dateStr: string): string => {
      if (!dateStr) return '';
      const parts = dateStr.split('-');
      if (parts.length !== 3) return dateStr;

      const year = Number(parts[0]);
      const monthIndex = Number(parts[1]) - 1;
      const day = Number(parts[2]);

      if (!year || monthIndex < 0 || monthIndex > 11 || !day) {
        return dateStr;
      }

      const monthName = datePickerLocale.months[monthIndex] ?? '';

      switch (wpDateFormat) {
        case 'F j, Y':
          return `${monthName} ${day}, ${year}`;
        case 'Y-m-d':
          return `${year}-${String(monthIndex + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
        case 'm/d/Y':
          return `${String(monthIndex + 1).padStart(2, '0')}/${String(day).padStart(2, '0')}/${year}`;
        case 'd/m/Y':
          return `${String(day).padStart(2, '0')}/${String(monthIndex + 1).padStart(2, '0')}/${year}`;
        case 'Y/m/d':
          return `${year}/${String(monthIndex + 1).padStart(2, '0')}/${String(day).padStart(2, '0')}`;
        case 'd.m.Y':
          return `${String(day).padStart(2, '0')}.${String(monthIndex + 1).padStart(2, '0')}.${year}`;
        case 'j. F Y':
          return `${day}. ${monthName} ${year}`;
        case 'j F Y':
          return `${day} ${monthName} ${year}`;
        default:
          return `${year}-${String(monthIndex + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
      }
    };

    const updateFormattedDate = (dateObj: any): void => {
      // Одинарная дата (клик по одному дню)
      if (typeof dateObj === 'string') {
        const normalized = normalizeYmd(dateObj);
        if (!normalized) {
          formattedDate.value = '';
          date.value = '';
          emit('update:modelValue', '');
          closeDatePicker();
          return;
        }

        const rangeObj = { from: normalized, to: normalized };
        formattedDate.value = formatSingleDate(normalized);
        date.value = rangeObj;
        emit('update:modelValue', rangeObj);
        closeDatePicker();
        return;
      }

      // Диапазон
      if (typeof dateObj === 'object' && dateObj) {
        const from = normalizeYmd(dateObj.from);
        const to = normalizeYmd(dateObj.to || dateObj.from);

        if (!from && !to) {
          formattedDate.value = '';
          date.value = '';
          emit('update:modelValue', '');
          closeDatePicker();
          return;
        }

        if (from === to) {
          formattedDate.value = formatSingleDate(from);
        } else {
          formattedDate.value = `${formatSingleDate(from)} - ${formatSingleDate(to)}`;
        }

        const rangeObj = { from, to };
        date.value = rangeObj;
        emit('update:modelValue', rangeObj);
        closeDatePicker();
        return;
      }

      // fallback — очистка
      formattedDate.value = '';
      date.value = '';
      emit('update:modelValue', '');
      closeDatePicker();
    };

    // Синк с внешним v-model (если значение меняется извне)
    watch(
      () => props.modelValue,
      (newVal) => {
        date.value = newVal as any;

        if (typeof newVal === 'object' && newVal && (newVal as any).from) {
          const from = normalizeYmd((newVal as any).from);
          const to = normalizeYmd((newVal as any).to || (newVal as any).from);

          if (from && to) {
            formattedDate.value =
              from === to
                ? formatSingleDate(from)
                : `${formatSingleDate(from)} - ${formatSingleDate(to)}`;
          } else {
            formattedDate.value = '';
          }
        } else {
          formattedDate.value = '';
        }
      },
      { immediate: true, deep: true }
    );

    onMounted(() => {
      document.addEventListener('click', handleClickOutside);
      window.addEventListener('resize', updateDeviceType);
      updateDeviceType();
    });

    onBeforeUnmount(() => {
      document.removeEventListener('click', handleClickOutside);
      window.removeEventListener('resize', updateDeviceType);
      updateDeviceType();
    });

    return {
      date,
      formattedDate,
      datePickerVisible,
      datepickerPopup,
      datepickerToggle,
      dateMask,
      datePickerLocale,
      wpStartOfWeek,
      openPicker,
      clearDate,
      closeDatePicker,
      handlePopoverClick,
      updateFormattedDate,
    };
  },
});
</script>

<style lang="scss">
.loyalty-suite-datepicker {
  display: flex;
  align-self: flex-start;
  height: 40px;
  align-items: center;
  padding: 4px 4px 4px 15px;
  margin-top: 15px;
  border: 1px solid var(--loyalty-suite-borders-60);
  border-radius: 8px;
  transition: 0.3s;
  position: relative;

  &:hover {
    cursor: pointer;
    border-color: var(--loyalty-suite-primary);
  }

  &__text {
    display: flex;
    font-size: 14px;
    font-weight: 400;
    color: var(--loyalty-suite-dark);
  }

  &__icon {
    display: flex;
    flex-shrink: 0;
    width: 30px;
    height: 100%;
    justify-content: center;
    align-items: center;
    background: var(--loyalty-suite-primary);
    margin-left: 15px;
    border-radius: 5px;

    &:hover {
      cursor: pointer;
    }

    .loyalty-suite-material-icons {
      font-size: 18px;
      color: var(--loyalty-suite-light);
    }
  }

  &__clear {
    display: flex;
    flex-shrink: 0;
    width: 20px;
    height: 100%;
    justify-content: center;
    align-items: center;
    margin-left: 10px;
    margin-right: -10px;

    .loyalty-suite-material-icons {
      font-size: 24px;
      color: var(--loyalty-suite-negative);
    }
  }

  &__close {
    display: flex;
    width: 100%;
    justify-content: flex-end;
  }
}

@media (max-width: 576px) {
  .loyalty-suite-datepicker {
    &__datepicker-text {
      font-size: 13px;
    }
  }
}
</style>
