<template>
  <div class="fields-container">
    <transition name="fadeIn">
      <DisclaimerReservation v-if="showDisclaimer" />
    </transition>

    <input-text
      model-name="title"
      :form-id="formId"
      :label="$_tr('label.title')"
      :rules="['required']"
      :default-value="defaultValue('title')"
    />

    <input-textarea
      model-name="reservation_description"
      :form-id="formId"
      :label="$_tr('label.description')"
      :default-value="defaultValue('reservation_description')"
    />

    <input-hidden
      model-name="cooldown"
      :form-id="formId"
      :default-value="defaultValue('cooldown', roomCooldown)"
      :current-value="roomCooldown"
    />

    <div class="user-fields-wrapper">
      <input-selectbox
        model-name="organizer"
        :form-id="formId"
        :label="$_tr('label.organizer')"
        :label-callback="user => $_username(user)"
        :async="{
          contentType: 'users',
          fields: ['uuid', 'lastname', 'firstname', 'image'],
          filters: {
            'is_maintenance:eq': 0,
            'status:eq': 1
          }
        }"
        :default-value="
          defaultValue('organizer', getUserInfos.uuid, item => item.uuid)
        "
        :extra-options-callback="user => ({ image: user.image })"
        object-value-key="uuid"
      >
        <template #default="{ node }">
          <user-item-selectbox
            :username="getCheckedData(node, ['raw', 'label'])"
            :image="getCheckedData(node, ['raw', 'extraOptions', 'image'])"
          />
        </template>
      </input-selectbox>

      <input-selectbox
        model-name="author"
        :form-id="formId"
        :label="$_tr('label.author')"
        :label-callback="user => $_username(user)"
        :readonly="true"
        :default-value="
          defaultValue('authors', getUserInfos.uuid, item => item.uuid)
        "
        :input-data="[defaultValue('authors', getUserInfos)]"
        :extra-options-callback="
          user => {
            return user && { image: user.image }
          }
        "
        object-value-key="uuid"
      >
        <template #default="{ node }">
          <user-item-selectbox
            :username="getCheckedData(node, ['raw', 'label'])"
            :image="getCheckedData(node, ['raw', 'extraOptions', 'image'])"
          />
        </template>
      </input-selectbox>
    </div>

    <input-date
      model-name="start_date"
      :form-id="formId"
      :disabled="disableDates"
      :day-options="{
        label: $_tr('label.start_date'),
        defaultValue: defaultValue(
          'start_date',
          heritedStartDate || new Date(),
          item => item * 1000
        ),
        clearButton: false
      }"
      :time-options="{
        label: $_tr('label.time'),
        defaultValue: defaultValue(
          'start_date',
          defaultReservationsTime('start_date', heritedStartDate),
          item => {
            if (isEdition) {
              const date = new Date(item * 1000)

              const hours = String(date.getHours()).padStart(2, '0')
              const minutes = String(date.getMinutes()).padStart(2, '0')

              return `${hours}:${minutes}`
            }

            return item
          }
        ),
        openOn: { h: 12 }
      }"
      @onDataChange="startDateChange"
    />

    <input-date
      model-name="end_date"
      :form-id="formId"
      :disabled="disableDates"
      :day-options="{
        label: $_tr('label.end_date'),
        defaultValue: defaultValue(
          'end_date',
          heritedStartDate || new Date(),
          item => item * 1000
        ),
        currentValue: startDate,
        clearButton: false
      }"
      :time-options="{
        label: $_tr('label.time'),
        defaultValue: defaultValue(
          'end_date',
          defaultReservationsTime('end_date', heritedStartDate),
          item => {
            if (isEdition) {
              const date = new Date(item * 1000)

              const hours = String(date.getHours()).padStart(2, '0')
              const minutes = String(date.getMinutes()).padStart(2, '0')

              return `${hours}:${minutes}`
            }

            return item
          }
        ),
        openOn: { h: 12 },
        currentValue: isEdition ? null : startTimePlusOneHour
      }"
      @onDataChange="endDateChange"
    />

    <input-selectbox
      model-name="frequency"
      :form-id="formId"
      :disabled="disableDates"
      :label="$_tr('label.frequency')"
      :input-data="frequenciesValues"
      :label-callback="item => $_tr(`frequencies.${item.labelKey}`)"
      :default-value="getDefaultValue()"
      @onDataChange="handleFrequencyChange"
    />

    <input-day
      v-if="freq"
      model-name="until"
      :form-id="formId"
      :label="$_tr('label.until')"
      :default-value="until"
      :callback="dayCallback"
    />

    <input-number
      model-name="seets"
      :form-id="formId"
      :label="$_tr('label.total')"
      :default-value="defaultValue('seets')"
    />

    <input-selectbox
      model-name="internal_users"
      :form-id="formId"
      :label="$_tr('label.internal_users')"
      :label-callback="user => $_username(user)"
      :async="{
        contentType: 'users',
        fields: ['uuid', 'lastname', 'firstname', 'image'],
        filters: {
          'is_maintenance:eq': 0,
          'status:eq': 1
        }
      }"
      :multiple="true"
      :input-data="users"
      :default-value="
        defaultValue('internal_users', [], item => {
          return item.data.map(user => user.uuid)
        })
      "
      :extra-options-callback="
        user => {
          return user && { image: user.image }
        }
      "
      object-value-key="uuid"
    >
      <template #default="{ node }">
        <user-item-selectbox
          :username="getCheckedData(node, ['raw', 'label'])"
          :image="getCheckedData(node, ['raw', 'extraOptions', 'image'])"
        />
      </template>
    </input-selectbox>

    <input-textarea
      v-show="!disableExternals"
      model-name="external_users"
      :form-id="formId"
      :label="$_tr('label.external_users')"
      :default-value="defaultValue('external_users')"
    />

    <input-textarea
      model-name="internal_comment"
      :form-id="formId"
      :label="$_tr('label.memo')"
      :default-value="defaultValue('internal_comment')"
    />

    <input-checkbox
      v-if="getCheckedData(itsData, 0)"
      model-name="information_technologies"
      :form-id="formId"
      :label="$_tr('label.it')"
      :input-data="itsData"
      :default-value="defaultItValue"
      :current-value="currentItData"
      object-label-key="title"
      object-value-key="uuid"
    />

    <input-checkbox
      v-if="getCheckedData(cateringsData, 0)"
      model-name="catering_services"
      :form-id="formId"
      :label="$_tr('label.catering')"
      :input-data="cateringsData"
      :current-value="currentCateringData"
      :default-value="defaultCateringValue"
      object-label-key="title"
      object-value-key="uuid"
    />

    <input-selectbox
      v-bind="roomField"
      model-name="rooms"
      :form-id="formId"
      :label="$_tr('label.rooms')"
      @onDataChange="handleRoomChange"
      @onInputMount="handleRoomChange"
    />

    <input-hidden
      v-if="isEdition"
      model-name="uuid"
      :form-id="formId"
      :default-value="defaultValue('uuid')"
    />
  </div>
</template>

<script>
import moment from 'moment'

import DisclaimerReservation from '../../inside-customs/components/agenda/DisclaimerReservation'

import ReservationsFields from '@inside-agenda/components/lib/sub-components/forms/ReservationsFields'

import { http } from '@inside-library/helpers/Http'

export default {
  name: 'reservations-fields',
  components: { DisclaimerReservation },
  extends: ReservationsFields,
  data() {
    return {
      roomCooldown: 0,
      roomType: false,
      itsData:
        this.getCheckedData(
          this.heritedData,
          'information_technologies.data'
        ) ||
        this.getCheckedData(
          this.heritedData,
          'parentData.information_technologies.data'
        ),
      cateringsData:
        this.getCheckedData(this.heritedData, 'catering_services.data') ||
        this.getCheckedData(
          this.heritedData,
          'parentData.catering_services.data'
        ),
      // Allow to reset checkboxes fields when the room is set
      showDisclaimer: false,
      isInitialized: false,
      startDate: null,
      startTimePlusOneHour: null,
      roomsData: {},
      currentCateringData: [],
      currentItData: [],
      startDateDisclaimer: {},
      endDateDisclaimer: {}
    }
  },
  computed: {
    disabledDates() {
      // if we edit a recurrent event and it isn't the 1st one
      if (this.isEdition && this.freq && this.currentStartDate) {
        const startDate = moment(this.currentStartDate.split(' ')[0]).format(
          'X'
        )

        if (moment(startDate * 1000).isBefore(moment())) {
          return true
        }
      }

      return false
    },
    cooldownInputData() {
      const data = []
      let i = 0

      while (i <= 60) {
        data.push({ labelKey: i, value: i })
        i += 5
      }

      return data
    },
    roomField() {
      return {
        objectLabelKey: 'title',
        objectValueKey: 'uuid',
        inputData: this.$_agendasData,
        defaultValue: this.defaultValue(
          'rooms',
          this.getCheckedData(this.parentData, 'uuid'),
          item => item.uuid
        )
      }
    },
    disableExternals() {
      return this.isAlive(this.roomType, 'uuid')
        ? this.roomType.uuid === '0271e7e6-546f-4029-82df-657dafb57623'
        : true
    },
    defaultCateringValue() {
      return this.defaultValue('catering_services', [], item => {
        return item.data.map(catering => catering.uuid)
      })
    },
    defaultItValue() {
      return this.defaultValue('information_technologies', [], item => {
        return item.data.map(it => it.uuid)
      })
    }
  },
  mounted() {
    this.roomType =
      this.getCheckedData(this.heritedData, 'parentData.rooms_category.uuid') ||
      this.getCheckedData(this.heritedData, 'rooms.rooms_category.uuid')
  },
  methods: {
    getDefaultValue() {
      const defaultFrequencyValue = this.defaultValue(
        'frequency',
        this.frequenciesValues[0],
        value => {
          const options = this.parseFrequency(value)

          return this.currentFrequency(options)
        }
      )

      return typeof defaultFrequencyValue === 'object' &&
        defaultFrequencyValue.value === 0
        ? 0
        : defaultFrequencyValue
    },
    startDateChange(data) {
      const { value } = data
      const [day, time] = value.split(' ')

      this.startDate = day
      this.startTimePlusOneHour = time

      const start = moment(time, 'HH:mm:ss')

      if (start.isValid()) {
        const hour = start.get('h')
        const minutes = start.get('m')
        const startDay = moment(day, 'YYYY-MM-DD').get('d')

        this.startDateDisclaimer = { hour, minutes }

        this.showDisclaimer =
          hour < 8 ||
          (hour === 18 ? minutes > 1 : hour > 18) ||
          startDay === 6 ||
          startDay === 0 ||
          (this.endDateDisclaimer.hour === 18
            ? this.endDateDisclaimer.minutes > 1
            : this.endDateDisclaimer.hour > 18)
      }

      if (this.startTimePlusOneHour) {
        this.startTimePlusOneHour = moment
          .utc(time, 'HH:mm:ss')
          .local()
          .add(1, 'h')
          .format('HH:mm:ss')

        if (moment(this.startTimePlusOneHour, 'HH:mm:ss').get('h') === 0) {
          this.startDate = moment
            .utc(this.startDate, 'YYYY-MM-DD')
            .local()
            .add(1, 'd')
            .format('YYYY-MM-DD')
        }
      }

      this.handleStartDateChange(data)
    },
    endDateChange(data) {
      const { value } = data
      const [day, time] = value.split(' ')

      const end = moment(time, 'HH:mm:ss')
      if (end.isValid()) {
        const hour = end.get('h')
        const minutes = end.get('m')
        const endDay = moment(day, 'YYYY-MM-DD').get('d')
        this.endDateDisclaimer = { hour, minutes }

        this.showDisclaimer =
          hour < 8 ||
          (hour === 18 ? minutes > 1 : hour > 18) ||
          endDay === 6 ||
          endDay === 0 ||
          this.startDateDisclaimer.hour < 8
      }
    },
    async handleRoomChange({ value }) {
      let data = this.roomsData[value]

      if (!data) {
        try {
          const { data: fetchedData } = await http.get('content/rooms', {
            fields: [
              'default_cooldown',
              { rooms_category: ['title', 'uuid'] },
              { information_technologies: ['title', 'uuid'] },
              { catering_services: ['title', 'uuid'] }
            ],
            filters: {
              'uuid:eq': value,
              status: 1
            }
          })

          data = fetchedData
        } catch (err) {
          throw new Error(err)
        }
      }

      this.itsData = data[0].information_technologies.data
      this.cateringsData = data[0].catering_services.data
      this.roomType = data[0].rooms_category
      this.roomCooldown = data[0].default_cooldown

      this.currentItData = this.defaultItValue.filter(item =>
        this.itsData.some(({ uuid }) => item === uuid)
      )
      this.currentCateringData = this.defaultCateringValue.filter(item =>
        this.cateringsData.some(({ uuid }) => item === uuid)
      )
    }
  }
}
</script>

<style lang="scss" scoped>
@use '@inside-library/styles/mixins/partials/common-mixin' as *;

.section-title {
  margin: var(--spacing-xl) 0 var(--spacing-s);
  font-size: var(--font-size-h5);
  font-weight: var(--font-weight-bold);
}

.user-fields-wrapper {
  @include desktop-only {
    display: flex;
    justify-content: space-between;

    .input-selectbox {
      width: calc(50% - 8px);
    }
  }
}
</style>
