<template>
  <DatePickerWrapper
    :selected-date="state.selectedDate"
    :placeholder="props.placeholder"
    :label="props.label"
    :disabled="props.disabled"
    :error="props.error"
    :error-text="props.errorText"
    ref="wrapper"
    @reset="reset"
  >
    <div class="picker-container no-title">
      <div class="picker-extended no-select">
        <div class="year-picker">
          <div class="icon lg-medium prev" @click="setYear(-1)">
            <SpIcon name="chevronLeft" />
          </div>
          <p class="h700 caps">
            {{ state.selectedYear }} {{ $t("dates.year") }}
          </p>
          <div class="icon lg-medium next" @click="setYear(1)">
            <SpIcon name="chevronRight" />
          </div>
        </div>
        <div class="month-picker h700">
          <div class="month-row row">
            <div
              class="col-md-4 col-2"
              :class="{ active: state.selectedMonth === i - 1 }"
              v-for="i of 12"
              :key="i"
            >
              <span @click="setMonth(i - 1)">
                {{ $t(`dates.month_short_${i}`) }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </DatePickerWrapper>
</template>

<script lang="ts">
import {
  defineComponent,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
} from "vue";
import FormMixin from "@/mixins/FormMixin";
import Pikaday from "pikaday";
import moment from "moment";
import { useI18n } from "vue-i18n";

export default defineComponent({
  mixins: [FormMixin],
  props: {
    format: {
      type: String,
      default: "DD / MMMM / YYYY",
    },
    valueFormat: {
      type: String,
      default: "DD/MM/YYYY",
    },
    maxDate: {
      type: Date,
      default: () => new Date(),
    },
    lang: {
      type: String,
      default: "ka",
    },
  },
  setup(props: any, { emit }) {
    const { t } = useI18n();
    const state = reactive<{
      selectedDate: string;
      selectedYear: number;
      selectedMonth: number;
      defaultValue: any;
      pikaday: any;
    }>({
      selectedDate: "",
      selectedYear: 0,
      selectedMonth: 0,
      defaultValue: null,
      pikaday: null,
    });

    const wrapper = ref(null) as any;

    onMounted((): void => {
      if (props.value) {
        const m = moment(props.value, props.valueFormat);
        m.locale(props.lang);

        state.selectedDate = m.format(props.format);

        state.defaultValue = m.toDate();

        state.selectedYear = state.defaultValue.getFullYear();
        state.selectedMonth = state.defaultValue.getMonth();
      } else {
        const date = new Date();
        state.selectedYear = date.getFullYear();
        state.selectedMonth = date.getMonth();
      }

      setTimeout(() => {
        initPikaday();
      }, 0);
    });

    onBeforeUnmount(() => {
      destroyPikaday();
    });

    const initPikaday = (): void => {
      if (!wrapper.value) {
        return;
      }

      const field = wrapper.value.$el.querySelector(
        "#pikaday"
      ) as HTMLInputElement;
      const container = wrapper.value.$el.querySelector(
        ".picker-container"
      ) as HTMLElement;
      const months: string[] = [];
      const weekdays: string[] = [];
      const weekdaysShort: string[] = [];

      for (let i = 1; i <= 6; i++) {
        weekdays.push(t(`dates.week_long_${i}`) as string);
        weekdaysShort.push(t(`dates.week_short_${i}`) as string);
      }
      weekdays.unshift(t(`dates.week_long_7`) as string);
      weekdaysShort.unshift(t(`dates.week_short_7`) as string);

      for (let i = 1; i <= 12; i++) {
        months.push(t(`dates.month_long_${i}`) as string);
      }

      state.pikaday = new Pikaday({
        field: field,
        container: container,
        bound: false,
        maxDate: props.maxDate,
        firstDay: 1,
        defaultDate: state.defaultValue,
        setDefaultDate: true,
        keyboardInput: false,
        i18n: {
          previousMonth: "",
          nextMonth: "",
          months,
          weekdays,
          weekdaysShort,
        },
        onSelect: (date: Date): void => {
          const m = moment(date);
          m.locale(props.lang);
          state.selectedDate = m.format(props.format);
          emit("input", m.format(props.valueFormat));
        },
      });
    };

    const destroyPikaday = (): void => {
      state.pikaday.destroy();
    };

    const setMonth = (monthNumber: number): void => {
      if (monthNumber < 0 || monthNumber > 11) {
        return;
      }

      state.selectedMonth = monthNumber;
      state.pikaday.gotoMonth(state.selectedMonth);
    };

    const setYear = (step: number): void => {
      if (step !== 1 && step !== -1) {
        return;
      }

      if (state.selectedYear <= 1960 && step < 0) {
        return;
      }

      state.selectedYear += step;
      state.pikaday.gotoYear(state.selectedYear);
    };

    const reset = (): void => {
      state.selectedDate = "";
      emit("input", null);
    };

    return {
      props,
      wrapper,
      reset,
      setYear,
      setMonth,
      state,
    };
  },
});
</script>

<style lang="scss">
.picker-container {
  display: flex;
  flex-direction: column;

  .picker-extended {
    padding: 0 0 24px;

    &:after {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: var(--background-secondary);
      z-index: -1;
    }

    .year-picker {
      text-align: center;
      position: relative;

      .icon {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        cursor: pointer;

        &.prev {
          left: 0;
        }

        &.next {
          right: 0;
        }
      }
    }

    .month-picker {
      margin: 0 -10px;

      .month-row {
        margin-top: 6px;

        div {
          margin-top: 12px;

          span {
            padding: 5px 0 3px;
            text-align: center;
            border-radius: 60px;
            cursor: pointer;
            transition: 0.3s ease;
            display: block;
            width: 50px;
            margin: 0 auto;

            &:hover {
              color: var(--blue);
            }
          }

          &.active {
            span {
              color: var(--blue);
              background-color: var(--blue-10);
            }
          }

          &:nth-of-type(3n + 1) {
            text-align: left;
          }

          &:nth-of-type(3n + 2) {
            text-align: center;
          }

          &:nth-of-type(3n + 3) {
            text-align: right;
          }
        }
      }
    }
  }

  @include screen-md() {
    flex-direction: row;

    .picker-extended {
      padding: 24px 12px;
      max-width: 270px;

      .month-picker {
        margin: 0;

        .month-row {
          div {
            padding-left: 4px;
            padding-right: 4px;

            span {
              width: 52px;
              padding: 3px 0;
            }
          }
        }
      }
    }
  }

  @include screen-lg() {
    .picker-extended {
      padding: 32px 16px;

      &:after {
        width: 100%;
        height: 100%;
        transform: none;
      }

      .month-picker {
        margin: 0;

        .month-row {
          margin-top: 15px;

          div {
            margin: 0;
            text-align: center;
            padding: 5px 0;

            span {
              width: 56px;
              padding: 4px 3px;
            }
          }
        }
      }
    }
  }
}
</style>
