<i18n>
{
  "th": {
    "periodSelector": {
      "column": "คอลัมน์",
      "today": "วันนี้",
      "thisWeek": "อาทิตย์นี้",
      "thisMonth": "เดือนนี้",
      "lastMonth": "เดือนที่แล้ว",
      "thisYear": "ปีนี้",
      "formatDate": "วว/ดด/ปป",
      "placeholder": "เลือกวันที่",
      "allDate": "ตลอดอายุการใช้งาน"
    }
  }
}
</i18n>

<template>
  <v-menu
    v-model="menu"
    :close-on-content-click="false"
    content-class="modern-scrollbar"
    nudge-top="-4px"
    transition="slide-y-transition"
    offset-y>
    <template v-slot:activator="{ on, attrs }">
      <v-text-field
        :style="{ width }"
        :value="dateDisplay"
        :label="columnDisplay"
        :placeholder="placeholder || $t('periodSelector.placeholder')"
        background-color="#ffffff"
        v-bind="attrs"
        class="snt-period-display--input"
        append-icon="mdi-calendar"
        dense
        outlined
        readonly
        hide-details
        v-on="on">
        <template #append>
          <div class="d-flex gap-2">
            <v-icon
              v-if="!!value[0] && !!value[1]"
              @click="$emit('input', [null, null])">
              mdi-close
            </v-icon>
            <v-icon
              color="secondary"
              @click="setMenu(true)">
              $snt_calendar_outline
            </v-icon>
          </div>
        </template>
      </v-text-field>
    </template>
    <v-date-picker
      :value="value"
      :title-date-format="titleDateFormat"
      :header-date-format="headerDateFormat"
      :month-format="monthFormat"
      :year-format="yearFormat"
      :selected-items-text="dateDisplay"
      :allowed-dates="validateRange"
      :class="{
        'snt-period-date-picker--column': selectColumn
      }"
      :max="maxDate"
      color="primary"
      range
      @input="checkDateFilter($event)">
      <div>
        <div class="d-flex gap-1 mb-6">
          <v-spacer />
          <v-btn
            v-if="!hideToday"
            class="px-3"
            color="primary"
            depressed
            rounded
            x-small
            @click="changeToday()">
            {{ $t('periodSelector.today') }}
          </v-btn>
          <v-btn
            v-if="!hideWeekly"
            class="px-3"
            color="primary"
            depressed
            rounded
            x-small
            @click="changeWeekly()">
            {{ $t('periodSelector.thisWeek') }}
          </v-btn>
          <v-btn
            v-if="!hideMonthly"
            class="px-3"
            color="primary"
            depressed
            rounded
            x-small
            @click="changeMonthly()">
            {{ $t('periodSelector.thisMonth') }}
          </v-btn>
          <v-btn
            v-if="!hideLastMonth"
            class="px-3"
            color="primary"
            depressed
            rounded
            x-small
            @click="changeLastMonth()">
            {{ $t('periodSelector.lastMonth') }}
          </v-btn>
          <v-btn
            v-if="!hideYearly"
            class="px-3"
            color="primary"
            depressed
            rounded
            x-small
            @click="changeYearly()">
            {{ $t('periodSelector.thisYear') }}
          </v-btn>
        </div>
        <div
          v-if="selectColumn"
          class="snt-period-field">
          <v-select
            :value="columnInput"
            :items="columns"
            :label="$t('periodSelector.column')"
            :menu-props="{
              'contentClass': 'modern-scrollbar',
              'transition':'slide-y-transition',
              'nudge-top': '-4px',
              'offset-y': true,
            }"
            :item-value="(item) => `${item.model}.${item.field}`"
            item-text="fullDisplay"
            hide-details
            return-object
            outlined
            dense
            @change="$emit('update:selected-column', $event)" />
        </div>
      </div>
    </v-date-picker>
  </v-menu>
</template>

<script>
export default {
  props: {
    value: {
      type: Array,
      default: () => ([])
    },
    label: {
      type: String,
      default: ''
    },
    width: {
      type: String,
      default: '300px'
    },
    columns: {
      type: Array,
      default: () => ([])
    },
    selectedColumn: {
      type: Object,
      default: () => ({
        fullDisplay: '',
        field: '',
        model: ''
      })
    },
    maxRange: {
      type: Number,
      default: undefined
    },
    selectColumn: Boolean,
    placeholder: {
      type: String,
      default: undefined
    },
    hideToday: Boolean,
    hideWeekly: Boolean,
    hideMonthly: Boolean,
    hideLastMonth: Boolean,
    hideYearly: Boolean
  },
  data () {
    return {
      menu: false,
      columnInput: '',
      format: 'YYYY-MM-DD'
    }
  },
  computed: {
    columnDisplay () {
      const column = this.columns.find((item) => item.model === this.columnInput.model && item.field === this.columnInput.field)
      return column ? column.fullDisplay : this.label
    },
    minRange () {
      return this.value.length === 1 ? this.value[0] : null
    },
    currentDate () {
      return this.$dayjs(new Date())
    },
    maxDate () {
      if (this.value[0]) {
        const startDate = this.$dayjs(this.value[0], [this.format])
        return startDate.add(this.maxRange, 'day').format('YYYY-MM-DD')
      }
      return undefined
    },
    dateDisplay () {
      if (!this.value[0] && !this.value[1]) return this.placeholder || this.$t('periodSelector.allDate')
      const startDate = this.$dayjs(this.value[0]).format('DD/MM/YY')
      let endDate = this.$t('periodSelector.formatDate')
      if (this.value[1]) {
        endDate = this.$dayjs(this.value[1]).format('DD/MM/YY')
      }
      return `${startDate} ~ ${endDate}`
    }
  },
  watch: {
    selectedColumn: {
      immediate: true,
      deep: true,
      handler (value) {
        this.columnInput = value
      }
    }
  },
  methods: {
    titleDateFormat (value) {
      if (!value[0] && !value[1]) return this.placeholder || this.$t('periodSelector.allDate')
      const startDate = this.$dayjs(value[0]).format('DD/MM/YY')
      const endDate = this.$dayjs(value[1]).format('DD/MM/YY')
      if (!value[1]) {
        return `${startDate}`
      }
      return `${startDate} ~ ${endDate}`
    },
    headerDateFormat (value) {
      const d = new Date(value)
      const year = d.getFullYear()
      const month = d.getMonth()
      const monthItems = [
        'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน',
        'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
      ]

      return `${monthItems[month] || month} ${year}`
    },
    monthFormat (value) {
      const d = new Date(value)
      const month = d.getMonth()
      const monthItems = ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.']
      return monthItems[month] || month
    },
    yearFormat (value) {
      return value
    },
    validateRange (date) {
      const pointDate = this.$dayjs(date, [this.format])
      const startDate = this.$dayjs(this.value[0], [this.format])
      return this.value.length === 1 ? !pointDate.isBefore(startDate) : true
    },
    changeToday () {
      const startDate = this.currentDate
      const endDate = this.currentDate
      this.$emit('input', [startDate.format(this.format), endDate.format(this.format)])
      this.setMenu(false)
    },
    changeWeekly () {
      const startDate = this.currentDate.day(0)
      const endDate = this.currentDate.day(6)
      this.$emit('input', [startDate.format(this.format), endDate.format(this.format)])
      this.setMenu(false)
    },
    changeMonthly () {
      const startDate = this.currentDate.date(1)
      const endDate = this.currentDate.date(this.currentDate.daysInMonth())
      this.$emit('input', [startDate.format(this.format), endDate.format(this.format)])
      this.setMenu(false)
    },
    changeLastMonth () {
      const startDate = this.currentDate.date(1).add(-1, 'month')
      const endDate = startDate.date(startDate.daysInMonth())
      this.$emit('input', [startDate.format(this.format), endDate.format(this.format)])
      this.setMenu(false)
    },
    changeYearly () {
      const startDate = this.currentDate.date(1).month(0)
      const dec = this.currentDate.month(11)
      const endDate = dec.date(dec.daysInMonth())
      this.$emit('input', [startDate.format(this.format), endDate.format(this.format)])
      this.setMenu(false)
    },
    checkDateFilter (dateFilter) {
      if (dateFilter.length > 1) {
        this.setMenu(false)
      }
      this.$emit('input', dateFilter)
    },
    setMenu (menu = false) {
      this.$_.delay(() => {
        this.menu = menu
      }, 300)
    }
  }
}
</script>
<style lang="scss" scoped>
  ::v-deep {
    .v-date-picker-title__date {
      padding-bottom: 0;
      line-height: 26px;
    }
    .snt-period-date-picker--column .v-picker__body {
      margin-top: 50px;
    }
  }
  .v-input {
    ::v-deep {
      .v-label {
        line-height: 22px;
      }
      fieldset {
        border: 1px solid currentColor;
      }
    }
  }
  .snt-period-display--input {
    max-width: 250px;
    .v-icon {
      font-size: 18px;
    }
    .v-input__append-inner {
      margin-top: 7px !important;
    }
  }
  .snt-period-field {
    position: absolute;
    top: 85px;
    left: 0;
    padding: 0 16px;
  }
</style>
