<template>
  <v-dialog
    ref="dialog"
    v-model="visible"
    width="340px"
    :return-value.sync="datetime"
  >
    <template v-slot:activator="{ on }">
      <sv-text-field
        v-model="inputValue"
        :label="$t(label)"
        :class="inputClass"
        :style="inputStyle"
        v-bind="$attrs"
        readonly
        v-on="on"
      ></sv-text-field>
    </template>
    <datetime-popup
      key="popup"
      v-model="datetime"
      type="time"
      :datetime="popupDate"
      :phrases="phrases"
      :week-start="weekStart"
      class="theme-dark"
      @confirm="confirm"
      @cancel="cancel"
    ></datetime-popup>
  </v-dialog>
</template>

<script>
import { DateTime } from "luxon"
import { weekStart } from "vue-datetime/src/util"
import DatetimePopup from "./DatetimePopup"

export default {
  name: "SvTimePicker",
  components: {
    DatetimePopup
  },

  inheritAttrs: false,

  props: {
    value: {
      type: String
    },
    label: {
      type: String,
      required: true
    },
    inputId: {
      type: String,
      default: null
    },
    inputClass: {
      type: [Object, Array, String],
      default: ""
    },
    inputStyle: {
      type: [Object, Array, String],
      default: ""
    },
    format: {
      type: [Object, String],
      default: null
    },
    phrases: {
      type: Object,
      default() {
        return {
          cancel: "Cancel",
          ok: "Ok"
        }
      }
    },
    use12Hour: {
      type: Boolean,
      default: false
    },
    hourStep: {
      type: Number,
      default: 1
    },
    minuteStep: {
      type: Number,
      default: 1
    },
    minDatetime: {
      type: String,
      default: null
    },
    maxDatetime: {
      type: String,
      default: null
    },
    auto: {
      type: Boolean,
      default: false
    },
    weekStart: {
      type: Number,
      default() {
        return weekStart()
      }
    },
    flow: {
      type: Array
    },
    title: {
      type: String
    }
  },

  data() {
    return {
      visible: false,
      datetime: this.setTime(this.value)
    }
  },

  computed: {
    inputValue: {
      get() {
        return (
          this.datetime?.toLocaleString({
            hour: "2-digit",
            minute: "2-digit",
            hour12: false
          }) || ""
        )
      },
      set(value) {
        this.datetime = null
        this.$emit("input", value || "")
      }
    },
    popupDate() {
      return this.datetime || this.newPopupDatetime()
    },
    popupMinDatetime() {
      return this.minDatetime ? DateTime.fromISO(this.minDatetime) : null
    },
    popupMaxDatetime() {
      return this.maxDatetime ? DateTime.fromISO(this.maxDatetime) : null
    }
  },

  watch: {
    value(newValue) {
      this.datetime = this.setTime(newValue)
    }
  },

  created() {
    this.emitInput()
  },

  methods: {
    emitInput() {
      this.$emit(
        "input",
        this.datetime?.toLocaleString({
          hour: "2-digit",
          minute: "2-digit",
          hour12: false
        }) || ""
      )
    },
    close() {
      this.visible = false
      this.$emit("close")
    },
    confirm(datetime) {
      this.$refs.dialog.save(datetime)
      this.emitInput()
      this.close()
    },
    cancel() {
      this.close()
    },
    newPopupDatetime() {
      let datetime = DateTime.utc().set({ seconds: 0, milliseconds: 0 })

      if (this.popupMinDatetime && datetime < this.popupMinDatetime) {
        datetime = this.popupMinDatetime.set({ seconds: 0, milliseconds: 0 })
      }

      if (this.popupMaxDatetime && datetime > this.popupMaxDatetime) {
        datetime = this.popupMaxDatetime.set({ seconds: 0, milliseconds: 0 })
      }

      if (this.minuteStep === 1) {
        return datetime
      }

      const roundedMinute =
        Math.round(datetime.minute / this.minuteStep) * this.minuteStep

      if (roundedMinute === 60) {
        return datetime.plus({ hours: 1 }).set({ minute: 0 })
      }

      return datetime.set({ minute: roundedMinute })
    },
    setTime(value) {
      if (!value) return null
      const [hours, minutes] = this.value.split(":")
      const date = new Date()
      const years = date.getFullYear()
      const months = date.getMonth()
      const day = date.getDate()

      const dateTime = new Date(years, months, day, +hours, +minutes, 0)
      return DateTime.fromISO(dateTime.toJSON())
    }
  }
}
</script>

<style>
.theme-dark .vdatetime-popup__header,
.theme-dark .vdatetime-calendar__month__day--selected > span > span,
.theme-dark .vdatetime-calendar__month__day--selected:hover > span > span {
  background: #000;
}

.theme-dark .vdatetime-year-picker__item--selected,
.theme-dark .vdatetime-time-picker__item--selected,
.theme-dark .vdatetime-popup__actions__button {
  color: #000;
}
</style>
