<template>
  <div class="mm-datepicker-panel">
    <div
      v-show="!selectTime"
      class="mm-datepicker-panel-header">
      <ui-icon
        name="chevronleft"
        size="0.875rem"
        @click="handleClickPrev"></ui-icon>
      <h2>
        <a
          class="mm-datepicker-panel-header-label"
          @click="switchpanel('year')">
          {{ yearLabel }}
        </a>
        <a
          v-show="panel === 'date'"
          class="mm-datepicker-panel-header-label"
          @click="switchpanel('month')">
          {{ t(`ui.datepicker.months[${(month)}]`) }}
        </a>
      </h2>
      <ui-icon
        name="chevronright"
        size="0.875rem"
        @click="handleClickNext"></ui-icon>
    </div>
    <div
      v-show="selectTime"
      class="mm-datepicker-panel-header mm-datepicker-panel-header__static">
      {{ pickedDateStr }}
    </div>

    <component
      :is="panel"
      v-show="!selectTime"
      :picked-date="pickedDate"
      :year="year"
      :month="month"
      :on-pick-year="handleYearPick"
      :on-pick-month="handleMonthPick"
      :on-pick="handlePick"
      :disabled-date="disabledDate"></component>
    <date-time
      v-show="selectTime"
      v-model="time"
      :visible="selectTime"
      :format="format"
      v-bind="disabledTime()"></date-time>

    <div
      v-if="showBottom"
      class="mm-datepicker-panel-footer">
      <a
        :disabled="!pickedDate"
        class="mm-datepicker-panel-switch"
        @click="handleSwitch">
        {{ panel === 'date-time' ? t('ui.datepicker.selectDate') : t('ui.datepicker.selectTime') }}
      </a>
      <ui-button
        :disabled="!pickedDate"
        type="primary"
        size="small"
        @click="closePanel">
        {{ t("ui.datepicker.confirm") }}
      </ui-button>
    </div>
  </div>
</template>

<script>
import { formatDate, today } from "../../../utils/date"
import Icon from "../../icon"
import Button from "../../button"
import DateTable from "../basic/date-table"
import MonthTable from "../basic/month-table"
import YearTable from "../basic/year-table"
import TimePanel from "../../time-picker/time-picker-panel"
import locale from "../../../mixins/locale"

export default {
  name: "mm-date-panel",
  components: {
    "ui-icon": Icon,
    "ui-button": Button,
    date: DateTable,
    month: MonthTable,
    year: YearTable,
    "date-time": TimePanel,
  },
  mixins: [locale],
  props: {
    value: [Date, String],
    type: {
      type: String,
      default: "date",
      validator: value => {
        return ["year", "month", "date", "date-time"].includes(value)
      },
    },
    disabledDate: Function,
    disabledTime: {
      type: Function,
      default: () => {},
    },
    visible: Boolean,
    format: {
      type: String,
    },
  },
  data() {
    const now = today()
    const date = this.value || now

    return {
      pickedDate: this.value,
      year: date.getFullYear(),
      month: date.getMonth(),
      time: this.value || "",
      panel: this.type === "date-time" ? "date" : this.type,
    }
  },
  computed: {
    yearLabel() {
      let label = `${this.year} ${this.t("ui.datepicker.year")}`
      if (this.panel === "year") {
        const startYear = Math.floor(this.year / 10) * 10
        label = `${startYear} ${this.t("ui.datepicker.year")} - ${startYear + 9} ${this.t(
          "ui.datepicker.year"
        )}`
      }

      return label
    },
    selectTime() {
      return this.panel === "date-time"
    },
    showBottom() {
      return this.type === "date-time" && (this.panel === "date" || this.panel === "date-time")
    },
    pickedDateStr() {
      return this.pickedDate ? formatDate(this.pickedDate, this.t("ui.datepicker.format.date")) : ""
    },
  },
  watch: {
    value(value) {
      this.pickedDate = value
    },
    time(value) {
      if (this.pickedDate) {
        const date = this.pickedDate.getDate()
        this.pickedDate = new Date(this.year, this.month, date, ...this.getTime(value))
      }
    },
    pickedDate(value) {
      this.$emit("input", value)
    },
    visible(value) {
      if (value && (this.type === "date" || this.type === "date-time")) {
        this.panel = "date"
      }
    },
  },
  methods: {
    getTime(time) {
      return [time.getHours(), time.getMinutes(), time.getSeconds()]
    },
    handlePick(value) {
      this.time = this.time || today()
      this.year = value.getFullYear()
      this.month = value.getMonth()

      const date = value.getDate()

      this.pickedDate = new Date(this.year, this.month, date, ...this.getTime(this.time))
    },
    handleYearPick(year) {
      this.year = year

      if (this.type === "year") {
        this.pickedDate = new Date(year, 0, 1)
      } else {
        this.switchpanel("month")
      }
    },
    handleMonthPick(month) {
      this.month = month
      if (this.type === "month") {
        this.pickedDate = new Date(this.year, month, 1)
      } else {
        this.switchpanel("date")
      }
    },
    switchpanel(panel) {
      this.panel = panel
      this.$emit("switch-panel")
    },
    handleClickPrev() {
      let year = this.year
      let month = this.month

      if (this.panel === "date") {
        if (month === 0) {
          month = 11
          year = year - 1
        } else {
          month = month - 1
        }
      } else if (this.panel === "month") {
        year = year - 1
      } else if (this.panel === "year") {
        year = year - 10
      }

      this.year = year
      this.month = month
    },
    handleClickNext() {
      let year = this.year
      let month = this.month

      if (this.panel === "date") {
        if (month === 11) {
          month = 0
          year = year + 1
        } else {
          month = month + 1
        }
      } else if (this.panel === "month") {
        year = year + 1
      } else if (this.panel === "year") {
        year = year + 10
      }

      this.year = year
      this.month = month
    },
    handleSwitch() {
      if (this.pickedDate) {
        this.switchpanel(this.panel === "date" ? "date-time" : "date")
      }
    },
    closePanel() {
      this.$emit("update:visible", false)
    },
  },
}
</script>
