<template>
  <dropdown
    class="date-picker"
    :show="show"
    @handleClose="show = false"
    :disabled="disabled"
  >
    <template v-slot:head>
      <div class="relative">
        <div class="wrap-action">
          <slot
            name="action"
            class="action"
          />
        </div>
        <form-input
          :placeholder="placeholder ? placeholder : dataPlaceholder"
          readonly
          @click="show = !show; selectMonth = false; selectYear = false"
          v-model="dataValue"
          :style="{display: slotAction == 0 ? '' : 'none'}"
        />
        <base-icon
          class="icon-date"
          :iconName="modelValue && clearAble ? 'close' : 'calendar_today'"
          height="20"
          width="20"
          @click="clickClear()"
          :style="{display: slotAction == 0 ? '' : 'none'}"
        />
      </div>
    </template>
    <template v-slot:list>
      <div v-if="mode == 'single'">
        <div v-if="selectMonth" class="calendar">
          <div class="header">
            <base-icon
              iconName="chevron_left"
              class="arrow"
              color="#3e7dc0"
              @click="movePrevious"
            />
            <span class="title cursor-pointer" @click="selectHeader()">
              {{ year }}
            </span>
            <base-icon
              iconName="chevron_right"
              class="arrow"
              color="#3e7dc0"
              @click="moveNext"
            />
          </div>
          <div class="flex flex-wrap items-center wrap-month">
            <div
              v-for="(item, index) in months"
              :key="index"
              class="month"
              :class="{ selected: selectedMonth(item), disabled: item.disabled }"
              @click="clickMonth(item)"
            >
              <span :class="{ today: item.isToday }">
                {{ item.label }}
              </span>
            </div>
          </div>
        </div>
        <div v-else-if="selectYear" class="calendar">
          <div class="header">
            <base-icon
              iconName="chevron_left"
              class="arrow"
              color="#3e7dc0"
              @click="movePrevious"
            />
            <span class="title">
              {{ listYear[0].year }} - {{ listYear[listYear.length - 1].year }}
            </span>
            <base-icon
              iconName="chevron_right"
              class="arrow"
              color="#3e7dc0"
              @click="moveNext"
            />
          </div>
          <div class="flex flex-wrap items-center wrap-month">
            <div
              v-for="(item, index) in listYear"
              :key="index"
              class="month"
              :class="{ selected: selectedYear(item.year), disabled: item.disabled }"
              @click="clickYear(item)"
            >
              <span :class="{ today: item.isToday }">{{ item.year }}</span>
            </div>
          </div>
        </div>
        <div v-else class="calendar">
          <div v-if="!['mmm', 'mm'].includes(formatDate)" class="header">
            <base-icon
              iconName="chevron_left"
              class="arrow"
              color="#3e7dc0"
              @click="movePrevious"
            />
            <div v-if="pickerType == 'day'" class="flex">
              <div class="cursor-pointer" @click="selectHeader()">
                <span class="title mr-1">
                  {{ monthLabels[month-1] }}
                </span>
                <span class="title">
                  {{ year }}
                </span>
              </div>
            </div>
            <span 
              v-else-if="pickerType == 'month'" 
              class="title cursor-pointer" 
              @click="selectHeader()"
            >
              {{ year }}
            </span>
            <span v-else-if="pickerType == 'year'" class="title">
              {{ listYear[0].year }} - {{ listYear[listYear.length - 1].year }}
            </span>
            <base-icon
              iconName="chevron_right"
              class="arrow"
              color="#3e7dc0"
              @click="moveNext"
            />
          </div>
          <div v-if="pickerType == 'day'">
            <div class="weekdays">
              <div
                class="weekday"
                v-for="(weekday, index) in weekdays"
                :key="index"
              >
                {{ weekday.label_3 }}
              </div>
            </div>
            <div class="week" v-for="(week, index) in weeks()" :key="index">
              <div
                class="day"
                :class="{
                  'not-in-month': !day.inMonth,
                  selected: day.isSelected && mode == 'single',
                  dragged:
                    (day.isDragged && mode == 'range') ||
                    (day.isSelected && mode == 'range'),
                  'start-date': borderRange(day, 'start'),
                  'end-date': borderRange(day, 'end'),
                  disabled: day.disabled,
                }"
                v-for="(day, idxDay) in week"
                :key="idxDay"
                @click="selectValue(day)"
                @mouseenter="enterDay(day)"
              >
                <span :class="{ today: day.isToday }">{{ day.label }}</span>
              </div>
            </div>
          </div>
          <div
            v-if="pickerType == 'month'"
            class="flex flex-wrap items-center wrap-month"
          >
            <div
              v-for="(item, index) in months"
              :key="index"
              class="month"
              :class="{ selected: item.isSelected, disabled: item.disabled }"
              @click="selectValue(item)"
            >
              <span :class="{ today: item.isToday }">{{ item.label }}</span>
            </div>
          </div>
          <div
            v-if="pickerType == 'year'"
            class="flex flex-wrap items-center wrap-month"
          >
            <div
              v-for="(item, index) in listYear"
              :key="index"
              class="month"
              :class="{ selected: item.isSelected, disabled: item.disabled }"
              @click="selectValue(item)"
            >
              <span :class="{ today: item.isToday }">{{ item.year }}</span>
            </div>
          </div>
        </div>
        <div
          v-if="slotActionFooter"
          class="px-6 pb-5 wrap-action-footer"
        >
          <slot name="actionFooter" />
        </div>
      </div>

      <!-- range picker -->
      <div v-if="mode == 'range'">
        <div v-if="pickerType == 'day'" class="date-picker range-picker">
          <div class="calendar flex flex-row">
            <div class="mr-6">
              <div class="header flex flex-col">
                <typo-text variant="body-2-bold" class="mb-2">
                  Tanggal Awal
                </typo-text>
                <div class="flex w-full">
                  <dropdown-select
                    name="monthStart"
                    class="pr-2"
                    :list="listMonthRange('start')"
                    v-model="valueMonthStart"
                  />
                  <dropdown-select
                    name="yearStart"
                    :list="listYearRange()"
                    v-model="valueYearStart"
                  />
                </div>
              </div>
              <div class="weekdays">
                <div
                  class="weekday"
                  v-for="(weekday, index) in weekdays"
                  :key="index"
                >
                  {{ weekday.label_3 }}
                </div>
              </div>
              <div class="week" v-for="(week, index) in weeks()" :key="index">
                <div
                  class="day"
                  :class="{
                    'not-in-month': !day.inMonth,
                    selected: day.isSelected && mode == 'single',
                    dragged:
                      (day.isDragged && mode == 'range' && day.label) ||
                      (day.isSelected && mode == 'range' && day.label),
                    'start-date': borderRange(day, 'start'),
                    'end-date': borderRange(day, 'end'),
                    disabled: day.disabled,
                  }"
                  v-for="(day, idxDay) in week"
                  :key="idxDay"
                  @click="selectValue(day)"
                  @mouseenter="enterDay(day)"
                >
                  <span :class="{ today: day.isToday }">{{ day.label }}</span>
                </div>
              </div>
            </div>
            <div>
              <div class="header flex flex-col">
                <typo-text variant="body-2-bold" class="mb-2">
                  Tanggal Akhir
                </typo-text>
                <div class="flex w-full">
                  <dropdown-select
                    name="monthEnd"
                    class="pr-2"
                    :list="listMonthRange('end')"
                    v-model="valueMonthEnd"
                  />
                  <dropdown-select
                    name="yearEnd"
                    :list="listYearRange('end')"
                    v-model="valueYearEnd"
                  />
                </div>
              </div>
              <div class="weekdays">
                <div
                  class="weekday"
                  v-for="(weekday, index) in weekdays"
                  :key="index"
                >
                  {{ weekday.label_3 }}
                </div>
              </div>
              <div
                class="week"
                v-for="(week, index) in weeks('end')"
                :key="index"
              >
                <div
                  class="day"
                  :class="{
                    'not-in-month': !day.inMonth,
                    selected: day.isSelected && mode == 'single',
                    dragged:
                      (day.isDragged && mode == 'range' && day.label) ||
                      (day.isSelected && mode == 'range' && day.label),
                    'start-date': borderRange(day, 'start'),
                    'end-date': borderRange(day, 'end'),
                    disabled: day.disabled,
                  }"
                  v-for="(day, idxDay) in week"
                  :key="idxDay"
                  @click="selectValue(day)"
                  @mouseenter="enterDay(day)"
                >
                  <span :class="{ today: day.isToday }">{{ day.label }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="calendar range-picker">
          <div class="header">
            <base-icon
              iconName="chevron_left"
              class="arrow"
              color="#3e7dc0"
              @click="movePrevious"
            />
            <span v-if="pickerType == 'month'" class="title">
              {{ year }}
            </span>
            <span v-else-if="pickerType == 'year'" class="title">
              {{ listYear[0].year }} - {{ listYear[listYear.length - 1].year }}
            </span>
            <base-icon
              iconName="chevron_right"
              class="arrow"
              color="#3e7dc0"
              @click="moveNext"
            />
          </div>
          <div
            v-if="pickerType == 'month'"
            class="flex flex-wrap items-center wrap-month"
          >
            <div
              v-for="(item, index) in months"
              :key="index"
              class="month"
              :class="{ 
                selected: item.isSelected, 
                disabled: item.disabled,
                dragged: (item.isDragged && mode == 'range'),
                'start-date': borderRange(item, 'start'),
                'end-date': borderRange(item, 'end'),
              }"
              @click="selectValue(item)"
              @mouseenter="enterDay(item)"
            >
              <span :class="{ today: item.isToday }">{{ item.label }}</span>
            </div>
          </div>
          <div
            v-if="pickerType == 'year'"
            class="flex flex-wrap items-center wrap-month"
          >
            <div
              v-for="(item, index) in listYear"
              :key="index"
              class="month"
              :class="{ 
                selected: item.isSelected,
                disabled: item.disabled,
                dragged: (item.isDragged && mode == 'range'),
                'start-date': borderRange(item, 'start'),
                'end-date': borderRange(item, 'end'),
              }"
              @click="selectValue(item)"
              @mouseenter="enterDay(item)"
            >
              <span :class="{ today: item.isToday }">{{ item.year }}</span>
            </div>
          </div>
        </div>
        <div
          v-if="slotActionFooter"
          class="px-6 pb-5 wrap-action-footer"
        >
          <slot name="actionFooter" />
        </div>
      </div>
    </template>
  </dropdown>
</template>

<script>
import BaseIcon from "@/components/Base/BaseIcon";
import TypoText from "@/components/Typography/TypoText";
import FormInput from "@/components/Form/FormInput";
import DropdownSelect from "@/components/Dropdown/DropdownSelect";
import Dropdown from "@/components/Dropdown";

export default {
  components: {
    BaseIcon,
    TypoText,
    FormInput,
    DropdownSelect,
    Dropdown,
  },
  props: {
    modelValue: {
      type: [String, Object, Date, Array, Number],
    },
    mode: {
      type: [String],
      default: "single",
      validator: function (value) {
        return ["single", "range"].indexOf(value) !== -1;
      },
    },
    pickerType: {
      type: [String],
      default: "day",
      validator: function (value) {
        return ["day", "month", "year"].indexOf(value) !== -1;
      },
    },
    clearAble: {
      type: Boolean,
      default: true
    },
    disabledDate: {
      type: [Array],
      default: null,
    },
    minMonth: {
      type: String,
      default: null,
    },
    maxMonth: {
      type: String,
      default: null,
    },
    formatDate: {
      type: [String],
      default: "yyyy-mm-dd",
      validator: function (value) {
        return [
          "dd-mm-yyyy",
          "dd/mm/yyyy",
          "dd mm yyyy",
          "yyyy-mm-dd",
          "yyyy/mm/dd",
          "yyyy mm dd",
          "dd-mmm-yyyy",
          "dd/mmm/yyyy",
          "dd mmm yyyy",
          "mm-yyyy",
          "mm/yyyy",
          "mm yyyy",
          "yyyy-mm",
          "yyyy/mm",
          "yyyy mm",
          "mmm-yyyy",
          "mmm/yyyy",
          "mmm yyyy",
          "yyyy",
          "mmm",
          "mm"
        ].indexOf(value) !== -1;
      },
    },
    autoClose: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    readonlyDate: {
      type: Boolean,
      default: false
    },
    maxDate: {
      type: [Object],
      default: null
    },
    minDate: {
      type: [Object],
      default: null
    },
    placeholder: {
      type: String,
      default: null
    },
    formatValue: {
      type: [String],
      default: "",
      validator: function (value) {
        return [
          "dd-mm-yyyy",
          "dd/mm/yyyy",
          "dd mm yyyy",
          "yyyy-mm-dd",
          "yyyy/mm/dd",
          "yyyy mm dd",
          "dd-mmm-yyyy",
          "dd/mmm/yyyy",
          "dd mmm yyyy",
          "mm-yyyy",
          "mm/yyyy",
          "mm yyyy",
          "yyyy-mm",
          "yyyy/mm",
          "yyyy mm",
          "mmm-yyyy",
          "mmm/yyyy",
          "mmm yyyy",
          "mmm",
          "mm",
          "yyyy",
          ""
        ].indexOf(value) !== -1;
      },
    },
  },
  data() {
    return {
      daysInMonths: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
      weekdayLabels: [
        "Minggu",
        "Senin",
        "Selasa",
        "Rabu",
        "Kamis",
        "Jumat",
        "Sabtu",
      ],
      monthLabels: [
        "Januari",
        "Februari",
        "Maret",
        "April",
        "Mei",
        "Juni",
        "Juli",
        "Agustus",
        "September",
        "Oktober",
        "November",
        "Desember",
      ],
      todayComps: {
        year: new Date().getFullYear(),
        month: new Date().getMonth() + 1,
        day: new Date().getDate(),
      },
      month: new Date().getMonth() + 1,
      year: new Date().getFullYear(),
      dragRange: null,
      show: false,
      dataValue: null,
      dataSelected: {},
      valueMonthStart: new Date().getMonth() + 1,
      valueYearStart: new Date().getFullYear(),
      valueMonthEnd: new Date().getMonth() + 2,
      valueYearEnd: new Date().getFullYear(),
      selectEnd: null,
      showYear: false,
      startYear: 1923,
      selectMonth: false,
      selectYear: false,
      slotAction: false,
      slotActionFooter: true
    };
  },
  computed: {
    // State for calendar header (no dependencies yet...)
    months() {
      let setValue;
      let year = this.previousMonthComps().year;
      if (this.pickerType == "day") {
        setValue = this.monthLabels.map((ml, i) => ({
          label: ml,
          label_3: ml.substring(0, 3),
          number: i + 1,
          isToday: i + 1 === this.todayComps.month && year === this.todayComps.year,
          disabled: this.checkDisableMonth(this.minMonth, this.maxMonth, new Date(this.year, i, 1)),
          date: new Date(this.year, i, 1),
        }));
      } else if (this.pickerType == "month") {
        setValue = this.monthLabels.map((ml, i) => ({
          label: ml,
          label_3: ml.substring(0, 3),
          month: i + 1,
          disabled: this.checkDisableMonth(this.minMonth, this.maxMonth, new Date(this.year, i, 1)),
          year: this.year,
          date: new Date(this.year, i, 1),
          isToday:
            i + 1 === this.todayComps.month && year === this.todayComps.year,
        }));
        setValue.forEach((element) => {
          this.configureDay(element);
        });
        this.setDisabled(setValue);
        this.setMaxDate(setValue)
        this.setMinDate(setValue)
      }

      return setValue;
    },
    // State for weekday header (no dependencies yet...)
    weekdays() {
      return this.weekdayLabels.map((wl, i) => ({
        label: wl,
        label_3: wl.substring(0, 1),
        number: i + 1,
      }));
    },
    // State for calendar header
    header() {
      const month = this.months[this.monthIndex()];
      return {
        month: month,
        year: this.year.toString(),
        shortYear: this.year.toString().substring(2, 4),
        label: month.label + " " + this.year,
      };
    },
    hasValue() {
      return this.dataDate(this.modelValue) && typeof this.dataDate(this.modelValue).getTime === "function";
    },
    valueTime() {
      if (this.hasValue) {
        this.year = this.dataDate(this.modelValue).getFullYear()
        this.month = this.dataDate(this.modelValue).getMonth() + 1
      }
      return this.hasValue ? this.dataDate(this.modelValue).getTime() : null;
    },
    valueIsValid() {
      return this.modelValue && this.modelValue.start && this.modelValue.end;
    },
    normalizedDragRange() {
      return this.normalizeRange(this.dataDate(this.dragRange));
    },
    listYear() {
      let setYear = [];
      let year = String(this.todayComps.year);
      for (let index = 0; index < 10; index++) {
        let dataYear = Number(year.slice(0, year.length - 1) + index);
        let checkDisabledYear = []
        if (this.disabledDate) {
          checkDisabledYear = this.disabledDate.filter(str => {
            return str == String(dataYear)
          })
        }
        let valueYear = {
          year: dataYear,
          isToday: dataYear === new Date().getFullYear(),
          date: new Date(dataYear, 0, 1),
          disabled: checkDisabledYear.length != 0 ? true : false
        };
        setYear.push(valueYear);
        this.setMaxDate(valueYear)
        this.setMinDate(valueYear)
        this.configureDay(valueYear);
      }
      return setYear;
    },
    dataPlaceholder() {
      let placeholder = this.formatDate.toLowerCase();
      if (this.pickerType == "year") {
        placeholder = placeholder
          .replace("-m", "")
          .replace("m-", "")
          .replace("/m", "")
          .replace("m/", "")
          .replace("m ", "")
          .replace(" m", "")
          .replace(/m/g, "")
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      } else if (this.pickerType == "month") {
        placeholder = placeholder
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      }

      if (this.mode == "range") {
        placeholder = placeholder + " ~ " + placeholder;
      }

      return placeholder;
    },
    optionYear() {
      let getOption = []
      for (let index = this.startYear; index < new Date().getFullYear() + 10; index++) {
        getOption.push(index)
      }
      return getOption
    }
  },
  watch: {
    normalizedDragRange(val) {
      // Any time drag changes, normalize it and emit 'drag' event
      this.$emit("drag", val ? { start: val.start, end: val.end } : null);
    },
    modelValue(newVal) {
      if (newVal) {
        this.setFormatDate(this.dataDate(this.modelValue));
      } else {
        this.dataValue = null;
      }
    },
    valueMonthStart(newVal) {
      if (newVal) {
        this.month = newVal;
      }
    },
    valueYearStart(newVal) {
      if (newVal) {
        this.year = newVal;
        this.valueYearEnd = newVal;
      }
    },
    valueYearEnd() {
      let dateStart = new Date(
        this.valueYearStart,
        this.valueMonthStart,
        1
      ).getTime();
      let dateEnd = new Date(
        this.valueYearEnd,
        this.valueMonthEnd,
        1
      ).getTime();
      if (dateStart >= dateEnd) {
        this.valueMonthEnd = this.valueMonthStart + 1;
      }
    },
    showYear(newVal) {
      if (newVal) {
        setTimeout(() => {
          document.getElementById(this.year).focus()
        }, 10);
      }
    },
    show(newVal) {
      if (newVal) {
        if (this.pickerType == "day" && this.mode == "single") {
          if (this.modelValue) {
            if (this.formatValue) {
              this.month = String(this.dataDate(this.modelValue).getMonth()+1)
              this.year = String(this.dataDate(this.modelValue).getFullYear());
            } else {
              this.month = String(new Date(this.dataDate(this.modelValue)).getMonth()+1)
              this.year = String(new Date(this.dataDate(this.modelValue)).getFullYear());
            }
          } else {
            this.month = this.todayComps.month;
            this.year = this.todayComps.year;
          }
        } 
      }
    }
  },
  mounted() {
    if (this.modelValue) {
      if (this.mode == "range") {
        this.dataSelected = {
          ...this.dataSelected, month: this.modelValue.start.getMonth() + 1
        }
        this.selectEnd = {
          ...this.selectEnd, month: this.modelValue.end.getMonth() + 1
        }
      }
      this.setFormatDate(this.dataDate(this.modelValue));
    }

    setTimeout(() => {
      if (document.getElementsByClassName("wrap-action")[0]) {
        this.slotAction = document.getElementsByClassName("wrap-action")[0].children.length
      }
      if (document.getElementsByClassName("wrap-action-footer")[0]) {
        this.slotActionFooter = document.getElementsByClassName("wrap-action-footer")[0].children.length
      }
    }, 1);
  },
  methods: {
    checkDisableMonth(minMonth, maxMonth, monthPicker){
      if(minMonth) {
        let convertMonth = minMonth.split("/")
        let propsMonth = new Date(convertMonth[1], convertMonth[0]-1 , 1)

        if(propsMonth.getTime() > monthPicker.getTime()) {
          return true
        } 
        return false
      }
      if(maxMonth) {
        let convertMonth = maxMonth.split("/")
        let propsMonth = new Date(convertMonth[1], convertMonth[0]-1 , 1)

        if(propsMonth.getTime() < monthPicker.getTime()) {
          return true
        } 
        return false
      }
      return false
    },
    moveThisMonth() {
      this.month = this.todayComps.month;
      this.year = this.todayComps.year;
    },
    moveNext() {
      if (this.pickerType == "day" && !this.selectMonth && !this.selectYear) {
        const { month, year } = this.nextMonthComps();
        this.month = month;
        this.year = year;
      } else if (this.pickerType == "month" && this.selectYear) {
        this.nextListYear()
      } else if (this.pickerType == "month" || this.selectMonth) {
        this.year++;
      } else if (this.pickerType == "year" || this.selectYear) {
        this.nextListYear()
      }
    },
    movePrevious() {
      if (this.pickerType == "day" && !this.selectMonth && !this.selectYear) {
        const { month, year } = this.previousMonthComps();
        this.month = month;
        this.year = month == 12 ? year - 1 : year;
      } else if (this.pickerType == "month" && this.selectYear) {
        this.prevListYear()
      } else if (this.pickerType == "month" || this.selectMonth) {
        this.year--;
      } else if (this.pickerType == "year" || this.selectYear) {
        this.prevListYear()
      }
    },
    selectValue(day) {
      switch (this.mode) {
        case "single":
          this.dataSelected = day;
          this.$emit("update:modelValue", this.setFormatValue(day.date));
          break;
        case "range":
          // Start new drag selection if not dragging
          if (!this.dragRange) {
            this.dataSelected = day
            // this.selectEnd = day
            this.dragRange = {
              start: day.date,
              end: day.date,
            };
            // Complete drag selection
          } else {
            this.selectEnd = day
            const { start, end } = this.normalizedDragRange;
            // Clear drag selection
            this.dragRange = null;
            this.$emit("update:modelValue", { start: this.formatDateRange(start, "start"), end: this.formatDateRange(end, "end") });
          }
          break;
      }
      this.show = !this.autoClose
    },
    configureDay(day) {
      switch (this.mode) {
        case "single":
          this.dataSelected = day;
          if (this.pickerType == "year") {
            day.isSelected = day.date.getTime() === this.valueTime;
          } else {
            day.isSelected = day.date.getTime() === this.valueTime && day.label;
          }
          break;
        case "range":
          day.isSelected =
            this.normalizeRange(this.dataDate(this.modelValue)) &&
            day.date.getTime() >=
              this.normalizeRange(this.dataDate(this.modelValue)).startTime &&
            day.date.getTime() <= this.normalizeRange(this.dataDate(this.modelValue)).endTime;
          day.isDragged =
            this.normalizedDragRange &&
            day.date.getTime() >= this.normalizedDragRange.startTime &&
            day.date.getTime() <= this.normalizedDragRange.endTime;
          break;
      }
    },
    enterDay(day) {
      if (!this.dragRange) return;
      // Update drag selection
      this.dragRange = {
        start: this.dragRange.start,
        end: day.date,
      };
    },
    // Ranges can privately have end date earlier than start date
    // This function will correct the order before exposing it to to other components
    normalizeRange(range) {
      if (!range) return null;
      const { start, end } = range;
      const startTime = this.pickerType == "year" ? start : start.getTime();
      const endTime = this.pickerType == "year" ? end : end.getTime();
      const isNormal = start < end;
      return {
        start: isNormal ? start : end,
        startTime: isNormal ? startTime : endTime,
        end: isNormal ? end : start,
        endTime: isNormal ? endTime : startTime,
      };
    },
    borderRange(day, position) {
      if (this.modelValue && this.mode == "range") {
        return String(day.date) == String(this.modelValue[position]);
      }
    },
    setDisabled(day) {
      if (this.disabledDate) {
        this.disabledDate.forEach(element => {
          if (this.pickerType == "day") {
            if (element == this.setFormatDate(day.date, true)) {
              day.disabled = true
            }
          } else if (this.pickerType == "month") {
            day.forEach(data => {
              if (element == this.setFormatDate(data.date, true)) {
                data.disabled = true
              }
            });
          }
        });
      }
    },
    setFormatDate(valueDate, flagDisabled) {
      let formatDate = this.formatDate.toLowerCase();
      let dayValue,
        monthValue,
        yearValue,
        dayValueEnd,
        monthValueEnd,
        yearValueEnd,
        dataDay,
        dataDayEnd,
        formatDay,
        dataMonth,
        dataMonthEnd,
        formatMonth,
        formatSplit;
      if (formatDate.search("-") != -1) {
        formatSplit = formatDate.split("-");
      } else if (formatDate.search("/") != -1) {
        formatSplit = formatDate.split("/");
      } else if (formatDate.search(" ") != -1) {
        formatSplit = formatDate.split(" ");
      }

      if (this.mode == "single") {
        if (!this.formatValue) {
          valueDate = new Date(valueDate)
        }
        dayValue = String(valueDate.getDate());
        monthValue = String(valueDate.getMonth() + 1);
        yearValue = String(valueDate.getFullYear());
      } else if (this.mode == "range") {
        if (valueDate.start) {
          dayValue = String(valueDate.start.getDate());
          dayValueEnd = String(valueDate.end.getDate());
          monthValue = String(valueDate.start.getMonth() + 1);
          monthValueEnd = String(valueDate.end.getMonth() + 1);
          yearValue = String(valueDate.start.getFullYear());
          yearValueEnd = String(valueDate.end.getFullYear());
        }

        if (formatSplit) {
          if (formatSplit.indexOf("d") != -1) {
            dataDayEnd = dayValueEnd;
          } else if (formatSplit.indexOf("dd") != -1) {
            dataDayEnd =
              dayValueEnd ? dayValueEnd.length == 1 ? "0" + dayValueEnd : dayValueEnd : dayValueEnd;
          } else if (formatSplit.indexOf("ddd") != -1) {
            dataDayEnd = this.weekdayLabels[this.selectEnd.weekday - 1];
          }
  
          if (formatSplit.indexOf("m") != -1) {
            dataMonthEnd = monthValueEnd;
          } else if (formatSplit.indexOf("mm") != -1) {
            dataMonthEnd =
              monthValueEnd ? monthValueEnd.length == 1 ? "0" + monthValueEnd : monthValueEnd : monthValueEnd;
          } else if (formatSplit.indexOf("mmm") != -1) {
            dataMonthEnd = this.monthLabels[monthValueEnd - 1];
          }
        }
      }

      if (this.pickerType == "day") {
        if (formatSplit) {
          if (formatSplit.indexOf("d") != -1) {
            dataDay = dayValue;
            formatDay = "d";
          } else if (formatSplit.indexOf("dd") != -1) {
            dataDay = dayValue ? dayValue.length == 1 ? "0" + dayValue : dayValue : dayValue;
            formatDay = "dd";
          } else if (formatSplit.indexOf("ddd") != -1) {
            dataDay = this.weekdayLabels[this.dataSelected.weekday - 1];
            formatDay = "ddd";
          }
        }
      }

      if (this.pickerType != "year") {
        if (this.formatDate == "mm") {
          dataMonth = monthValue ? monthValue.length == 1 ? "0" + monthValue : monthValue : monthValue;
          formatMonth = "mm";
        } else if (this.formatDate == "mmm") {
          dataMonth = this.monthLabels[monthValue - 1];
          formatMonth = "mmm";
        } else {
          if (formatSplit) {
            if (formatSplit.indexOf("m") != -1) {
              dataMonth = monthValue;
              formatMonth = "m";
            } else if (formatSplit.indexOf("mm") != -1) {
              dataMonth = monthValue ? monthValue.length == 1 ? "0" + monthValue : monthValue : monthValue;
              formatMonth = "mm";
            } else if (formatSplit.indexOf("mmm") != -1) {
              dataMonth = this.monthLabels[monthValue - 1];
              formatMonth = "mmm";
            }
          }
        }
      }

      let setDataValue
      if (this.mode == "single") {
        formatDate = !dataDay
          ? formatDate
            .replace("-d", "")
            .replace("d-", "")
            .replace("/d", "")
            .replace("d/", "")
            .replace("d ", "")
            .replace(" d", "")
            .replace(/d/g, "")
          : formatDate;
        if (!["mmm", "mm"].includes(this.formatDate)) {
          formatDate = !dataMonth
            ? formatDate
              .replace("-m", "")
              .replace("m-", "")
              .replace("/m", "")
              .replace("m/", "")
              .replace("m ", "")
              .replace(" m", "")
              .replace(/m/g, "")
            : formatDate; 
        }
        if (!flagDisabled) {
          this.dataValue = formatDate
            .replace(formatDay, dataDay)
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } else {
          setDataValue = formatDate
            .replace(formatDay, dataDay)
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        }
      } else if (this.mode == "range") {
        let setStart = formatDate
          .replace(formatDay, dataDay)
          .replace(formatMonth, dataMonth)
          .replace("yyyy", yearValue);
        let setEnd = formatDate
          .replace(formatDay, dataDayEnd)
          .replace(formatMonth, dataMonthEnd)
          .replace("yyyy", yearValueEnd);
        if (!flagDisabled) {
          this.dataValue = setStart + " ~ " + setEnd;
        } else {
          setDataValue = setStart + " ~ " + setEnd;
        }
      }
      return !flagDisabled ? this.dataValue : setDataValue
    },
    setFormatValue(valueDate) {
      let setDataValue
      if (this.formatValue) {
        let formatDate = this.formatValue.toLowerCase();
        let dayValue,
          monthValue,
          yearValue,
          dayValueEnd,
          monthValueEnd,
          yearValueEnd,
          dataDay,
          dataDayEnd,
          formatDay,
          dataMonth,
          dataMonthEnd,
          formatMonth,
          formatSplit;
          if (formatDate.search("-") != -1) {
          formatSplit = formatDate.split("-");
        } else if (formatDate.search("/") != -1) {
          formatSplit = formatDate.split("/");
        } else if (formatDate.search(" ") != -1) {
          formatSplit = formatDate.split(" ");
        }
  
        if (this.mode == "single") {
          dayValue = String(valueDate.getDate());
          monthValue = String(valueDate.getMonth() + 1);
          yearValue = String(valueDate.getFullYear());
        } else if (this.mode == "range") {
          if (valueDate.start) {
            dayValue = String(valueDate.start.getDate());
            dayValueEnd = String(valueDate.end.getDate());
            monthValue = String(valueDate.start.getMonth() + 1);
            monthValueEnd = String(valueDate.end.getMonth() + 1);
            yearValue = String(valueDate.start.getFullYear());
            yearValueEnd = String(valueDate.end.getFullYear());
          }
  
          if (formatSplit) {
            if (formatSplit.indexOf("d") != -1) {
              dataDayEnd = dayValueEnd;
            } else if (formatSplit.indexOf("dd") != -1) {
              dataDayEnd =
                dayValueEnd ? dayValueEnd.length == 1 ? "0" + dayValueEnd : dayValueEnd : dayValueEnd;
            } else if (formatSplit.indexOf("ddd") != -1) {
              dataDayEnd = this.weekdayLabels[this.selectEnd.weekday - 1];
            }
    
            if (formatSplit.indexOf("m") != -1) {
              dataMonthEnd = monthValueEnd;
            } else if (formatSplit.indexOf("mm") != -1) {
              dataMonthEnd =
                monthValueEnd ? monthValueEnd.length == 1 ? "0" + monthValueEnd : monthValueEnd : monthValueEnd;
            } else if (formatSplit.indexOf("mmm") != -1) {
              dataMonthEnd = this.monthLabels[monthValueEnd - 1];
            }
          }
        }
  
        if (this.pickerType == "day") {
          if (formatSplit) {
            if (formatSplit.indexOf("d") != -1) {
              dataDay = dayValue;
              formatDay = "d";
            } else if (formatSplit.indexOf("dd") != -1) {
              dataDay = dayValue ? dayValue.length == 1 ? "0" + dayValue : dayValue : dayValue;
              formatDay = "dd";
            } else if (formatSplit.indexOf("ddd") != -1) {
              dataDay = this.weekdayLabels[this.dataSelected.weekday - 1];
              formatDay = "ddd";
            }
          }
        }
  
        if (this.pickerType != "year") {
          if (this.formatValue == "mm") {
            dataMonth = monthValue ? monthValue.length == 1 ? monthValue : monthValue : monthValue;
            formatMonth = "mm";
          } else if (this.formatValue == "mmm") {
            dataMonth = this.monthLabels[monthValue - 1];
            formatMonth = "mmm";
          } else {
            if (formatSplit) {
              if (formatSplit.indexOf("m") != -1) {
                dataMonth = monthValue;
                formatMonth = "m";
              } else if (formatSplit.indexOf("mm") != -1) {
                dataMonth = monthValue ? monthValue.length == 1 ? "0" + monthValue : monthValue : monthValue;
                formatMonth = "mm";
              } else if (formatSplit.indexOf("mmm") != -1) {
                dataMonth = this.monthLabels[monthValue - 1];
                formatMonth = "mmm";
              }
            }
          }
        }
  
        if (this.mode == "single") {
          formatDate = !dataDay
            ? formatDate
              .replace("-d", "")
              .replace("d-", "")
              .replace("/d", "")
              .replace("d/", "")
              .replace("d ", "")
              .replace(" d", "")
              .replace(/d/g, "")
            : formatDate;
          if (!["mmm", "mm"].includes(this.formatDate)) {
            formatDate = !dataMonth
              ? formatDate
                .replace("-m", "")
                .replace("m-", "")
                .replace("/m", "")
                .replace("m/", "")
                .replace("m ", "")
                .replace(" m", "")
                .replace(/m/g, "")
              : formatDate; 
          }
          setDataValue = formatDate
            .replace(formatDay, dataDay)
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } 
        // else if (this.mode == "range") {
        //   let setStart = formatDate
        //     .replace(formatDay, dataDay)
        //     .replace(formatMonth, dataMonth)
        //     .replace("yyyy", yearValue);
        //   let setEnd = formatDate
        //     .replace(formatDay, dataDayEnd)
        //     .replace(formatMonth, dataMonthEnd)
        //     .replace("yyyy", yearValueEnd);
        //   setDataValue = setStart + " ~ " + setEnd;
        // }
      } else {
        setDataValue = valueDate.toISOString()
      }
      return setDataValue
    },
    clickClear() {
      if (!this.modelValue) {
        this.show = !this.show
        this.selectMonth = false
        this.selectYear = false 
      } else {
        if (this.clearAble) {
          this.dataSelected = {};
          this.dataValue = null
          this.month = this.todayComps.month
          this.$emit("update:modelValue", null);
        } 
      }
    },
    listMonthRange(position) {
      let _this = this;
      let listMonth = [
        { id: `month${position}1`, label: "Januari", name: "", value: 1 },
        { id: `month${position}2`, label: "Februari", name: "", value: 2 },
        { id: `month${position}3`, label: "Maret", name: "", value: 3 },
        { id: `month${position}4`, label: "April", name: "", value: 4 },
        { id: `month${position}5`, label: "Mei", name: "", value: 5 },
        { id: `month${position}6`, label: "Juni", name: "", value: 6 },
        { id: `month${position}7`, label: "Juli", name: "", value: 7 },
        { id: `month${position}8`, label: "Agustus", name: "", value: 8 },
        { id: `month${position}9`, label: "September", name: "", value: 9 },
        { id: `month${position}10`, label: "Oktober", name: "", value: 10 },
        { id: `month${position}11`, label: "November", name: "", value: 11 },
        { id: `month${position}12`, label: "Desember", name: "", value: 12 },
      ];

      if (this.valueYearStart == this.valueYearEnd && position == "end") {
        for (let index = _this.valueMonthStart - 1; index >= 0; index--) {
          listMonth[index] = {
            ...listMonth[index],
            hidden: true,
          };
        }
        if (this.valueMonthStart >= this.valueMonthEnd) {
          this.valueMonthEnd = this.valueMonthStart + 1;
        }
        if (this.valueMonthStart == 12) {
          this.valueMonthEnd = 1;
          this.valueYearEnd = this.valueYearStart + 1;
        }
      }
      return listMonth;
    },
    weeks(position) {
      const weeks = [];
      let previousMonth = true,
        thisMonth = false,
        nextMonth = false;
      let previousMonthComps =
        position == "end"
          ? this.previousMonthComps("end")
          : this.previousMonthComps();
      let firstWeekdayInMonth =
        position == "end"
          ? this.firstWeekdayInMonth("end")
          : this.firstWeekdayInMonth();
      let valueMonth = position == "end" ? this.valueMonthEnd : this.month;
      let valueYear = position == "end" ? this.valueYearEnd : this.year;
      let daysInMonth =
        position == "end" ? this.daysInMonth("end") : this.daysInMonth();
      let nextMonthComps =
        position == "end" ? this.nextMonthComps("end") : this.nextMonthComps();
      let day = previousMonthComps.days - firstWeekdayInMonth + 2;
      let month = previousMonthComps.month;
      let year = previousMonthComps.year;
      for (let w = 1; w <= 6 && !nextMonth; w++) {
        const week = [];
        for (let d = 1; d <= 7; d++) {
          if (previousMonth && d >= firstWeekdayInMonth) {
            day = 1;
            month = valueMonth;
            year = valueYear;
            previousMonth = false;
            thisMonth = true;
          }

          const dayInfo = {
            label: day && thisMonth ? day.toString() : "",
            day,
            weekday: d,
            week: w,
            month,
            year,
            date: new Date(year, month - 1, day),
            inMonth: thisMonth,
            isToday:
              day === this.todayComps.day &&
              month === this.todayComps.month &&
              year === this.todayComps.year,
            disabled: false
          };
          this.configureDay(dayInfo);
          this.setDisabled(dayInfo);
          this.setMaxDate(dayInfo)
          this.setMinDate(dayInfo)
          week.push(dayInfo);

          if (thisMonth && day >= daysInMonth) {
            thisMonth = false;
            nextMonth = true;
            day = 1;
            month = nextMonthComps.month;
            year = nextMonthComps.year;
          } else {
            day++;
          }
        }

        weeks.push(week);
      }
      return weeks;
    },
    monthIndex(position) {
      let month = position == "end" ? this.valueMonthEnd : this.month;
      return month - 1;
    },
    isLeapYear(position) {
      let year = position == "end" ? this.valueYearEnd : this.year;
      return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    },
    previousMonthComps(position) {
      let valueMonth = position == "end" ? this.valueMonthEnd : this.month;
      let valueYear = position == "end" ? this.valueYearEnd : this.year;
      if (Number(valueMonth) === 1) {
        return {
          days: this.daysInMonths[11],
          month: 12,
          year: Number(valueYear)
        };
      } else {
        return {
          days:
            valueMonth === 3 && this.isLeapYear("end")
              ? 29
              : this.daysInMonths[valueMonth - 2],
          month: Number(valueMonth) - 1,
          year: valueYear,
        };
      }
    },
    nextMonthComps(position) {
      let month = position == "end" ? this.valueMonthEnd : this.month;
      let year = position == "end" ? this.valueYearEnd : this.year;
      let isLeapYear =
        position == "end" ? this.isLeapYear("end") : this.isLeapYear();

      if (Number(month) === 12)
        return {
          days: this.daysInMonths[0],
          month: 1,
          year: Number(year) + 1,
        };
      return {
        days: month === 2 && isLeapYear ? 29 : this.daysInMonths[month],
        month: Number(month) + 1,
        year: year,
      };
    },
    firstWeekdayInMonth(position) {
      let year = position == "end" ? this.valueYearEnd : this.year;
      let monthIndex =
        position == "end" ? this.monthIndex("end") : this.monthIndex();
      return new Date(year, monthIndex, 1).getDay() + 1;
    },
    daysInMonth(position) {
      let month = position == "end" ? this.valueMonthEnd : this.month;
      let isLeapYear =
        position == "end" ? this.isLeapYear("end") : this.isLeapYear();
      let monthIndex =
        position == "end" ? this.monthIndex("end") : this.monthIndex();

      // Check for Februari in a leap year
      if (month === 2 && isLeapYear) return 29;
      // ...Just a normal month
      return this.daysInMonths[monthIndex];
    },
    listYearRange(position) {
      let setYear = [];
      let year =
        position == "end" ? this.valueYearStart : this.todayComps.year - 10;
      let i = position == "end" ? 10 : 20;
      for (let index = 0; index < i; index++) {
        let dataYear = year + index;
        let valueYear = {
          id: (position == "end" ? "yearEnd" : "yearStart") + dataYear,
          label: dataYear,
          name: "",
          value: dataYear,
        };
        setYear.push(valueYear);
      }
      return setYear;
    },
    dataDate(dateValue) {
      let dataDate, month, year, day, monthEnd, yearEnd, dayEnd
      let splitCode = {
        "dd-mm-yyyy": {
          code: "-",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "dd/mm/yyyy": {
          code: "/",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "dd mm yyyy": {
          code: " ",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "yyyy-mm-dd": {
          code: "-",
          day: { yyyy: 0, mm: 1, dd: 2 }
        },
        "yyyy/mm/dd": {
          code: "/",
          day: { yyyy: 0, mm: 1, dd: 2 }
        },
        "yyyy mm dd": {
          code: " ",
          day: { yyyy: 0, mm: 1, dd: 2 }
        },
        "dd-mmm-yyyy": {
          code: "-",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "dd/mmm/yyyy": {
          code: "/",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "dd mmm yyyy": {
          code: " ",
          day: { dd: 0, mm: 1, yyyy: 2 }
        },
        "mm-yyyy": {
          code: "-",
          month: { mm: 0, yyyy: 1 }
        },
        "mm/yyyy": {
          code: "/",
          month: { mm: 0, yyyy: 1 }
        },
        "mm yyyy": {
          code: " ",
          month: { mm: 0, yyyy: 1 }
        },
        "yyyy-mm": {
          code: "-",
          month: { yyyy: 0, mm: 1 }
        },
        "yyyy/mm": {
          code: "/",
          month: { yyyy: 0, mm: 1 }
        },
        "yyyy mm": {
          code: " ",
          month: { yyyy: 0, mm: 1 }
        },
        "mmm-yyyy": {
          code: "-",
          month: { mm: 0, yyyy: 1 }
        },
        "mmm/yyyy": {
          code: "/",
          month: { mm: 0, yyyy: 1 }
        },
        "mmm yyyy": {
          code: " ",
          month: { mm: 0, yyyy: 1 }
        },
        "yyyy": {
          code: "",
          month: { yyyy: 0 }
        },
        "mmm": {
          code: "",
          month: { mm: 0 }
        },
        "mm": {
          code: "",
          month: { mm: 0 }
        }
      }
      let listMonth = {
        "Januari": 1,
        "Februari": 2,
        "Maret": 3,
        "April": 4,
        "Mei": 5,
        "Juni": 6,
        "Juli": 7,
        "Agustus": 8,
        "September": 9,
        "Oktober": 10,
        "November": 11,
        "Desember": 12
      }
      if (dateValue) {
        if (this.mode == "single") {
          if (this.formatValue) {
            if (this.pickerType == "year") {
              dataDate = new Date(dateValue, 0, 1)
            } else if (this.pickerType == "month") {
              if (this.formatValue == "mmm") {
                dataDate = new Date(new Date().getFullYear(), listMonth[dateValue]-1, 1)
              } else if (this.formatValue == "mm") {
                dataDate = new Date(new Date().getFullYear(), dateValue-1, 1)
              } else {
                let getData = dateValue.split(splitCode[this.formatValue].code)
                year = getData[splitCode[this.formatValue].month.yyyy]
                month = listMonth[getData[splitCode[this.formatValue].month.mm]] ? listMonth[getData[splitCode[this.formatValue].month.mm]] : Number(getData[splitCode[this.formatValue].month.mm])
                dataDate = new Date(year, month-1, 1)
              }
            } else if (this.pickerType == "day") {
              let getData = dateValue.split(splitCode[this.formatValue].code)
              year = getData[splitCode[this.formatValue].day.yyyy]
              month = listMonth[getData[splitCode[this.formatValue].day.mm]] ? listMonth[getData[splitCode[this.formatValue].day.mm]] : Number(getData[splitCode[this.formatValue].day.mm])
              day = getData[splitCode[this.formatValue].day.dd]
              dataDate = new Date(year, month-1, day)
            }
          } else {
            dataDate = new Date(dateValue)
          }
        } else if (this.mode == "range") {
          dataDate = dateValue
          if (typeof dataDate.start == "string") {
            let getDataStart
            let getDataEnd
            if (this.pickerType == "day") {
              getDataStart = dataDate.start.split(splitCode[this.formatDate].code)
              year = getDataStart[splitCode[this.formatDate].day.yyyy]
              month = listMonth[getDataStart[splitCode[this.formatDate].day.mm]] ? listMonth[getDataStart[splitCode[this.formatDate].day.mm]] : Number(getDataStart[splitCode[this.formatDate].day.mm])
              day = getDataStart[splitCode[this.formatDate].day.dd]
              dataDate.start = new Date(year, month-1, day)
    
              getDataEnd = dataDate.end.split(splitCode[this.formatDate].code)
              yearEnd = getDataEnd[splitCode[this.formatDate].day.yyyy]
              monthEnd = listMonth[getDataEnd[splitCode[this.formatDate].day.mm]] ? listMonth[getDataEnd[splitCode[this.formatDate].day.mm]] : Number(getDataEnd[splitCode[this.formatDate].day.mm])
              dayEnd = getDataEnd[splitCode[this.formatDate].day.dd]
              dataDate.end = new Date(yearEnd, monthEnd-1, dayEnd)
            } else if (this.pickerType == "month") {
              getDataStart = dataDate.start.split(splitCode[this.formatDate].code)
              year = getDataStart[splitCode[this.formatDate].month.yyyy]
              month = listMonth[getDataStart[splitCode[this.formatDate].month.mm]] ? listMonth[getDataStart[splitCode[this.formatDate].month.mm]] : Number(getDataStart[splitCode[this.formatDate].month.mm])
              dataDate.start = new Date(year, month-1, 1)
    
              getDataEnd = dataDate.end.split(splitCode[this.formatDate].code)
              yearEnd = getDataEnd[splitCode[this.formatDate].month.yyyy]
              monthEnd = listMonth[getDataEnd[splitCode[this.formatDate].month.mm]] ? listMonth[getDataEnd[splitCode[this.formatDate].month.mm]] : Number(getDataEnd[splitCode[this.formatDate].month.mm])
              dataDate.end = new Date(yearEnd, monthEnd-1, 1)
            } else if (this.pickerType == "year") {
              dataDate.start = new Date(dataDate.start, 0, 1)
              dataDate.end = new Date(dataDate.end, 0, 1)
            }
          }
        }
        return dataDate
      }
    },
    formatDateRange(val, param) {
      let formatDate = this.formatDate.toLowerCase();
      let dayValue,
        monthValue,
        yearValue,
        dayValueEnd,
        monthValueEnd,
        yearValueEnd,
        dataDay,
        dataDayEnd,
        formatDay,
        dataMonth,
        dataMonthEnd,
        formatMonth,
        formatSplit;

      if (formatDate.search("-") != -1) {
        formatSplit = formatDate.split("-");
      } else if (formatDate.search("/") != -1) {
        formatSplit = formatDate.split("/");
      } else if (formatDate.search(" ") != -1) {
        formatSplit = formatDate.split(" ");
      }

      if (param == "start") {
        dayValue = String(val.getDate());
        monthValue = String(val.getMonth() + 1);
        yearValue = String(val.getFullYear());
      } else if (param == "end") {
        dayValueEnd = String(val.getDate());
        monthValueEnd = String(val.getMonth() + 1);
        yearValueEnd = String(val.getFullYear());
      }
      if (formatSplit) {
        if (formatSplit.indexOf("d") != -1) {
          if (param == "start") {
            dataDay = dayValue;
          } else if (param == "end") {
            dataDayEnd = dayValueEnd;
          }
          formatDay = "d";
        } else if (formatSplit.indexOf("dd") != -1) {
          if (param == "start") {
            dataDay = dayValue.length == 1 ? "0" + dayValue : dayValue;
          } else if (param == "end") {
            dataDayEnd = dayValueEnd.length == 1 ? "0" + dayValueEnd : dayValueEnd;
          }
          formatDay = "dd";
        } else if (formatSplit.indexOf("ddd") != -1) {
          if (param == "start") {
            dataDay = this.weekdayLabels[this.dataSelected.weekday - 1];
          } else if (param == "end") {
            dataDayEnd = this.weekdayLabels[this.selectEnd.weekday - 1];
          }
          formatDay = "ddd";
        }
  
        if (formatSplit.indexOf("m") != -1) {
          if (param == "start") {
            dataMonth = monthValue;
          } else if (param == "end") {
            dataMonthEnd = monthValueEnd;
          }
          formatMonth = "m";
        } else if (formatSplit.indexOf("mm") != -1) {
          if (param == "start") {
            dataMonth = monthValue.length == 1 ? "0" + monthValue : monthValue;
          } else if (param == "end") {
            dataMonthEnd = monthValueEnd.length == 1 ? "0" + monthValueEnd : monthValueEnd;
          }
          formatMonth = "mm";
        } else if (formatSplit.indexOf("mmm") != -1) {
          if (param == "start") {
            dataMonth = this.monthLabels[monthValue - 1];
          } else if (param == "end") {
            dataMonthEnd = this.monthLabels[monthValueEnd - 1];
          }
          formatMonth = "mmm";
        }
      }

      if (this.pickerType == "year") {
        formatDate = formatDate
          .replace("-m", "")
          .replace("m-", "")
          .replace("/m", "")
          .replace("m/", "")
          .replace("m ", "")
          .replace(" m", "")
          .replace(/m/g, "")
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      } else if (this.pickerType == "month") {
        formatDate = formatDate
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      }

      if (param == "start") {
        let setStart
        if (this.pickerType == "day") {
          setStart = formatDate
            .replace(formatDay, dataDay)
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } else if (this.pickerType == "month") {
          setStart = formatDate
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } else if (this.pickerType == "year") {
          setStart = formatDate
            .replace("yyyy", yearValue);
        }

        return setStart
      } else if (param == "end") {
        let setEnd
        if (this.pickerType == "day") {
          setEnd = formatDate
            .replace(formatDay, dataDayEnd)
            .replace(formatMonth, dataMonthEnd)
            .replace("yyyy", yearValueEnd);
        } else if (this.pickerType == "month") {
          setEnd = formatDate
            .replace(formatMonth, dataMonthEnd)
            .replace("yyyy", yearValueEnd);
        } else if (this.pickerType == "year") {
          setEnd = formatDate
            .replace("yyyy", yearValueEnd);
        }

        return setEnd
      }
    },
    formatValueRange(val, param) {
      let formatDate = this.formatValue.toLowerCase();
      let dayValue,
        monthValue,
        yearValue,
        dayValueEnd,
        monthValueEnd,
        yearValueEnd,
        dataDay,
        dataDayEnd,
        formatDay,
        dataMonth,
        dataMonthEnd,
        formatMonth,
        formatSplit;

      if (formatDate.search("-") != -1) {
        formatSplit = formatDate.split("-");
      } else if (formatDate.search("/") != -1) {
        formatSplit = formatDate.split("/");
      } else if (formatDate.search(" ") != -1) {
        formatSplit = formatDate.split(" ");
      }

      if (param == "start") {
        dayValue = String(val.getDate());
        monthValue = String(val.getMonth() + 1);
        yearValue = String(val.getFullYear());
      } else if (param == "end") {
        dayValueEnd = String(val.getDate());
        monthValueEnd = String(val.getMonth() + 1);
        yearValueEnd = String(val.getFullYear());
      }
      
      if (formatSplit) {
        if (formatSplit.indexOf("d") != -1) {
          if (param == "start") {
            dataDay = dayValue;
          } else if (param == "end") {
            dataDayEnd = dayValueEnd;
          }
          formatDay = "d";
        } else if (formatSplit.indexOf("dd") != -1) {
          if (param == "start") {
            dataDay = dayValue.length == 1 ? "0" + dayValue : dayValue;
          } else if (param == "end") {
            dataDayEnd = dayValueEnd.length == 1 ? "0" + dayValueEnd : dayValueEnd;
          }
          formatDay = "dd";
        } else if (formatSplit.indexOf("ddd") != -1) {
          if (param == "start") {
            dataDay = this.weekdayLabels[this.dataSelected.weekday - 1];
          } else if (param == "end") {
            dataDayEnd = this.weekdayLabels[this.selectEnd.weekday - 1];
          }
          formatDay = "ddd";
        }
  
        if (formatSplit.indexOf("m") != -1) {
          if (param == "start") {
            dataMonth = monthValue;
          } else if (param == "end") {
            dataMonthEnd = monthValueEnd;
          }
          formatMonth = "m";
        } else if (formatSplit.indexOf("mm") != -1) {
          if (param == "start") {
            dataMonth = monthValue.length == 1 ? "0" + monthValue : monthValue;
          } else if (param == "end") {
            dataMonthEnd = monthValueEnd.length == 1 ? "0" + monthValueEnd : monthValueEnd;
          }
          formatMonth = "mm";
        } else if (formatSplit.indexOf("mmm") != -1) {
          if (param == "start") {
            dataMonth = this.monthLabels[monthValue - 1];
          } else if (param == "end") {
            dataMonthEnd = this.monthLabels[monthValueEnd - 1];
          }
          formatMonth = "mmm";
        }
      }
      
      if (this.pickerType == "year") {
        formatDate = formatDate
          .replace("-m", "")
          .replace("m-", "")
          .replace("/m", "")
          .replace("m/", "")
          .replace("m ", "")
          .replace(" m", "")
          .replace(/m/g, "")
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      } else if (this.pickerType == "month") {
        formatDate = formatDate
          .replace("-d", "")
          .replace("d-", "")
          .replace("/d", "")
          .replace("d/", "")
          .replace("d ", "")
          .replace(" d", "")
          .replace(/d/g, "");
      }

      if (param == "start") {
        let setStart
        if (this.pickerType == "day") {
          setStart = formatDate
            .replace(formatDay, dataDay)
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } else if (this.pickerType == "month") {
          setStart = formatDate
            .replace(formatMonth, dataMonth)
            .replace("yyyy", yearValue);
        } else if (this.pickerType == "year") {
          setStart = formatDate
            .replace("yyyy", yearValue);
        }

        return setStart
      } else if (param == "end") {
        let setEnd
        if (this.pickerType == "day") {
          setEnd = formatDate
            .replace(formatDay, dataDayEnd)
            .replace(formatMonth, dataMonthEnd)
            .replace("yyyy", yearValueEnd);
        } else if (this.pickerType == "month") {
          setEnd = formatDate
            .replace(formatMonth, dataMonthEnd)
            .replace("yyyy", yearValueEnd);
        } else if (this.pickerType == "year") {
          setEnd = formatDate
            .replace("yyyy", yearValueEnd);
        }

        return setEnd
      }
    },
    clickYear(year) {
      this.year = year.year
      setTimeout(() => {
        if (this.pickerType == "day") {
          this.selectYear = false
          this.selectMonth = true
        } else if (this.pickerType == "month") {
          this.selectYear = false
        }
      }, 0);
      this.todayComps.year = new Date().getFullYear();
    },
    clickMonth(month) {
      let getMonth = this.monthLabels.indexOf(month.label)
      this.month = getMonth+1
      setTimeout(() => {
        this.selectMonth = false
      }, 0);
    },
    selectedMonth(date) {
      let getMonth = String(date.date.getMonth()+1)
      let getYear = String(date.date.getFullYear())
      if (this.dataValue) {
        let dataMonth = String(this.dataDate(this.modelValue).getMonth()+1)
        let dataYear = String(this.dataDate(this.modelValue).getFullYear())
        if (dataMonth+dataYear == getMonth+getYear) {
          return true
        }
      }
      return false
    },
    selectedYear(year) {
      if (this.modelValue) {
        if (year == this.dataDate(this.modelValue).getFullYear()) {
          return true
        }
      }
      return false
    },
    selectHeader() {
      if (this.pickerType == "day") {
        if (!this.selectMonth) {
          setTimeout(() => {
            this.selectMonth = true
          }, 0);
        } else {
          setTimeout(() => {
            this.selectMonth = false
            this.selectYear = true
          }, 0);
        }
      } else if (this.pickerType == "month") {
        setTimeout(() => {
          this.selectYear = true
        }, 0);
      }
    },
    setMaxDate(day) {
      if (this.maxDate) {
        if (this.pickerType == "day") {
          if (day.label) {
            if (this.maxDate.getTime() < day.date.getTime()) {
              day.disabled = true
            }
          }
        } else if (this.pickerType == "month") {
          day.forEach(element => {
            if (this.maxDate.getTime() < element.date.getTime()) {
              element.disabled = true
            }
          });
        } else if (this.pickerType == "year") {
          if (this.maxDate.getTime() < day.date.getTime()) {
            day.disabled = true
          }
        }
      }
    },
    setMinDate(day) {
      if (this.minDate) {
        if (this.pickerType == "day") {
          if (day.label) {
            if (this.minDate.getTime() > day.date.getTime()) {
              day.disabled = true
            }
          }
        } else if (this.pickerType == "month") {
          if (day.length) {
            day.forEach(element => {
              if (this.minDate.getTime() > element.date.getTime()) {
                element.disabled = true
              }
            });
          } else {
            if (this.minDate.getFullYear() > day.date.getFullYear()) {
              day.disabled = true
            }
          }
        } else if (this.pickerType == "year") {
          if (this.minDate.getTime() > day.date.getTime()) {
            day.disabled = true
          }
        }
      }
    },
    nextListYear() {
      let year = String(this.todayComps.year);
      year = String(Number(year.slice(0, year.length - 1)) + 1) + 0;
      this.todayComps.year = Number(year);
    },
    prevListYear() {
      let year = String(this.todayComps.year);
      year = String(Number(year.slice(0, year.length - 1)) - 1) + 0;
      this.todayComps.year = Number(year);
    },
    handleClick() {
      this.show = !this.show
      this.selectMonth = false
      this.selectYear = false
    }
  },
};
</script>

<style lang="scss">
@use "@/assets/style/_color.scss" as *;

.date-picker {
  .wrap-action-footer {
    display: flex;
    justify-content: right;
    margin-top: -16px;

    .primary-btn {
      background: #3e7dc0 !important;
      border-color: #3e7dc0 !important;
      color: #ffffff !important;
    }
  }

  .picker-month {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
    background: #fff;
  }
  
  .icon-date {
    position: absolute;
    top: 0;
    right: 0;
    margin: 8px 11px 0 0;
    cursor: pointer;
  }

  input {
    cursor: pointer;
  }

  * {
    box-sizing: border-box;
  }

  .calendar {
    padding: 24px;
    background: #fff;
    width: fit-content;

    .wrap-month {
      max-width: 292px;

      .month {
        width: calc(100% / 3 - 2px);
        padding: 10px 0;
        color: $neutral-6;
        font-size: 12px;
        text-align: center;
        cursor: pointer;
        margin: 0 1px;
      }

      .selected {
        color: $neutral-0;
        font-weight: 700;
      }
    }

    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: $neutral-0;
      color: $neutral-6;
      margin-bottom: 16px;

      .arrow {
        font-size: 1.8rem;
        font-weight: 500;
        user-select: none;
        flex-grow: 0;
        cursor: pointer;
        color: $dark-blue-4;
      }

      .title {
        flex-grow: 1;
        font-size: 14px;
        font-weight: 700;
        text-align: center;
      }

      #month,
      #day {
        cursor: pointer;
        .dropdown {
          .dropdown-content {
            min-width: fit-content;
            margin-left: -12px;

            .wrap-option {
              overflow: auto;
              max-height: 160px;

              .active {
                background: #e8f2fb;
              }
            }
          }
        }
      }
    }

    .weekdays {
      display: flex;
      margin: 0 -1px;
      justify-content: center;
    }

    .weekday {
      width: 37px;
      height: 40px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: $neutral-4;
      cursor: default;
      font-size: 12px;
      font-weight: 700;
      margin: 0 1px;
    }

    .week {
      display: flex;
      margin: 0 -1px;
      justify-content: center;
    }

    .day {
      display: flex;
      justify-content: center;
      align-items: center;
      color: $neutral-6;
      cursor: pointer;
      width: 37px;
      height: 36px;
      font-size: 12px;
      font-weight: 400;
    }

    .day:hover,
    .month:hover {
      background: $dark-blue-2;
      border-radius: 6px;
    }

    .today {
      border-bottom: 2px solid $dark-blue-4;
    }

    .not-in-month {
      cursor: default;
      pointer-events: none;
    }

    .selected,
    .selected:hover {
      background: $dark-blue-4;
      border-radius: 6px;
      color: $neutral-0;
    }

    .dragged,
    .dragged:hover {
      background-color: $clear-blue-2;
      color: $neutral-6;
      border-radius: 0px;
      font-weight: 400;
    }

    .disabled {
      background: $neutral-1 !important;
      color: $neutral-2 !important;
      pointer-events: none;
      border-radius: 6px;
    }

    .start-date {
      border-left: 4px solid $clear-blue-4;
    }

    .end-date {
      border-right: 4px solid $clear-blue-4;
    }
  }
}

.range-picker {
  .calendar {
    .header {
      align-items: flex-start;
    }
  }

  .wrap-month {
    .selected {
      background-color: $dark-blue-2;
      color: #383e45 !important;
      border-radius: 0px;
      font-weight: 400;
    }

    .selected:hover {
      border-radius: 0px;
      background-color: $dark-blue-2;
    }

    .disabled {
      color: $neutral-2 !important;
    }

    .month {
      margin: 0px !important;
      width: calc(100% / 3) !important;
    }
  }
}
</style>
