<template>
  <div class="hive-date">
    <Header
      :year="year"
      :month="month"
      :type="type"
      :on-prev-or-next="clickHeader"
      :on-type-change="onTypeChange"
    />

    <Day
      :class="{ 'hive-date__sub-panel--hide': type !== 'date' }"
      :first-day-of-week="$attrs.firstDayOfWeek"
      :weeks="weeks"
      :on-click="clickDate"
    />

    <Month
      :class="{ 'hive-date__sub-panel--hide': type !== 'month' }"
      :first-day-of-week="$attrs.firstDayOfWeek"
      :months="months"
      :on-click="clickMonth"
    />

    <Year
      :class="{ 'hive-date__sub-panel--hide': type !== 'year' }"
      :first-day-of-week="$attrs.firstDayOfWeek"
      :years="years"
      :on-click="clickYear"
    />
  </div>
</template>

<script>
import Header from '../basic/header';
import Day from '../basic/day';
import Month from '../basic/month';
import Year from '../basic/year';

import {
  getWeeks,
  getYears,
  getMonths,
  flagActive,
  subtractMonth,
  addMonth,
  getToday } from '../util';

export default {
  name: 'HiveDatePickerDatePanel',
  components: {
    Header,
    Day,
    Month,
    Year
  },
  inheritAttrs: false,
  props: {
    mode: { type: String, default: 'date', validator(v) { return ['year', 'month', 'date'].indexOf(v) > -1; } },
    value: { type: Date, default: () => getToday() }
  },
  data() {
    return {
      year: this.value.getFullYear(),
      month: this.value.getMonth(),
      type: this.mode
    };
  },
  computed: {
    weeks() {
      const { year, month } = this;
      console.log(year, month, this.options.firstDayOfWeek);
      return flagActive(getWeeks({ year, month }, this.options), { start: this.value });
    },
    years() {
      const newValue = new Date(this.year, this.month);
      return flagActive(getYears(this.year, this.options), { start: this.mode === 'year' ? this.value : newValue, type: 'year' });
    },
    months() {
      const newValue = new Date(this.year, this.month);
      return flagActive(getMonths(this.year, this.options), { start: this.mode === 'month' ? this.value : newValue, type: 'month' });
    },
    options() {
      const {
        disabledDate,
        minDate,
        maxDate
      } = this.$attrs;
      const firstDayOfWeek = this.$attrs.firstDayOfWeek || this.$attrs['first-day-of-week'];
      return { disabledDate, minDate, maxDate, firstDayOfWeek };
    }
  },
  methods: {
    onTypeChange(type) {
      this.type = type;
    },
    clickDate(date) {
      this.$emit('change', date);
    },
    clickMonth(date) {
      if (this.mode === 'month') {
        this.$emit('change', date);
      } else {
        this.type = 'date';
        this.year = date.getFullYear();
        this.month = date.getMonth();
      }
    },
    clickYear(date) {
      if (this.mode === 'year') {
        this.$emit('change', date);
      } else {
        this.type = 'month';
        this.year = date.getFullYear();
      }
    },
    clickHeader(target, action) {
      if (target === 'year' && action === 'prev') {
        this.year -= 1;
      }

      if (target === 'year' && action === 'next') {
        this.year += 1;
      }

      if (target === 'month' && action === 'prev') {
        const prev = subtractMonth(new Date(this.year, this.month), 1);
        this.year = prev.getFullYear();
        this.month = prev.getMonth();
      }

      if (target === 'month' && action === 'next') {
        const next = addMonth(new Date(this.year, this.month), 1);
        this.year = next.getFullYear();
        this.month = next.getMonth();
      }
    }
  }
};
</script>
