<i18n>
{
  "en": {
    "statements": {
      "InviteDialog": {
        "slotsAreNotAvailable": "Slots are not available",
        "pleaseGenerateSlotsForService": "Please generate slots for the service or notify an administrator",
        "goToSchedule": "Go to schedule",
        "dialogTitle": "Creating of an invitation to appointment",
        "start": "start",
        "end": "end",
        "office": "Office number",
        "inviteComment": "Comment",
        "doneButton": "Send",
        "slotsHaveNotFound": "Time-slots for the service have not found",
        "inviteSentFailed": "Error when inviting an appointment",
        "inviteSentSuccess": "Appointment invitation sent",
        "dateLessThanAvailable": "Date is less than aveilible",
        "dateFurcherThanAvailable": "Date is furcher than aveilible",
        "wrongDate": "Date is wrong",
        "wrongAreaId": "Office number should not include such symbols",
        "emptyAreaId":"Sending an invitation without an account"
        }
    }
  },
  "ru": {
    "statements": {
      "InviteDialog": {
        "slotsAreNotAvailable": "Не найдено доступных слотов для записи",
        "pleaseGenerateSlotsForService": "Пожалуйста создайте расписание для этого сервиса или обратитесь к администратору",
        "goToSchedule": "Перейти к расписанию",
        "dialogTitle": "Формирование приглашения на очный приём",
        "start": "Запись на приём (с):",
        "end": "Запись на приём (по):",
        "office": "Кабинет",
        "inviteComment": "Коментарий к приглашению",
        "doneButton": "Отправить",
        "slotsHaveNotFound": "Слоты для сервиса не найдены",
        "inviteSentFailed": "Ошибка при приглашении на приём",
        "inviteSentSuccess": "Приглашение на приём отправлено",
        "dateLessThanAvailable": "Дата меньше доступной",
        "dateFurcherThanAvailable": "Дата больше доступной",
        "wrongDate": "Не верная дата",
        "wrongAreaId": "Номер кабинета содержит недопустимые символы",
        "emptyAreaId":"Отправляется приглашение без кабинета"
      }
    }
  }
}
</i18n>
<template>
  <div>
    <q-btn 
      @click="openDialogWindow()"
      icon="insert_invitation"
      style="color:#616161"
      tooltip="new"
      />
      <q-dialog v-model="dialog" >
        <q-card
          class="no-shadow"
          :style="{
            maxWidth: '80vw',
            width: '700px',
          }"
        >
        <q-card-section class="text-h6">
          {{$t('statements.InviteDialog.dialogTitle')}}
        </q-card-section>
        <template v-if="slotsAvailable || loading">
          <q-card-section class="row">
            <div class="col-4 self-center q-pb-md"> {{$t('statements.InviteDialog.start')}}</div>
            <div class="col-8">
              <q-input  filled v-model="startDate" mask="##.##.####" :rules="[testDateRange]">
                  <template v-slot:append>
                    <q-icon name="event" class="cursor-pointer">
                      <q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
                        <q-date
                          v-model="startDate"
                          mask="DD.MM.YYYY"
                        >
                          <div class="row items-center justify-end">
                            <q-btn v-close-popup label="Закрыть" color="primary" flat />
                          </div>
                        </q-date>
                      </q-popup-proxy>
                    </q-icon>
                  </template>
                </q-input>
            </div>
          </q-card-section>
          <q-card-section class="q-pt-none row">
            <div class="col-4 self-center q-pb-md "> {{$t('statements.InviteDialog.end')}}</div>
            <div class="col-8">
              <q-input filled v-model="endDate" mask="##.##.####" :rules="[testDateRange]">
                <template v-slot:append>
                  <q-icon name="event" class="cursor-pointer">
                    <q-popup-proxy ref="qDateProxy" cover transition-show="scale" transition-hide="scale">
                      <q-date
                        v-model="endDate"
                        mask="DD.MM.YYYY"
                      >
                        <div class="row items-center justify-end">
                          <q-btn v-close-popup label="Закрыть" color="primary" flat />
                        </div>
                      </q-date>
                    </q-popup-proxy>
                  </q-icon>
                </template>
              </q-input>
            </div> 
          </q-card-section>
          <q-card-section class="q-pt-none q-pb-md row">
            <div class="col-4 self-center"> {{$t('statements.InviteDialog.office')}}</div>
            <div class="col-8">
              <q-input
                v-model="areaId"
                filled
                required
                type="text"
                :rules="[testAtreaId]"
                :disable="receivedareaId"
              />
            </div>
          </q-card-section>

          <q-card-section class="q-pt-md row">
            <div class="col-4 self-center"> {{$t('statements.InviteDialog.inviteComment')}}</div>
            <div class="col-8">
              <q-input
                v-model="inviteComment"
                filled
                required
                type="textarea"
                />
            </div>
          </q-card-section>
          <q-card-actions
            class="full-width flex justify-end"
          >
            <q-btn 
            :label="$t('statements.InviteDialog.doneButton')" 
            color="primary" 
            @click="inviteToMeeting()" 
            v-close-popup
            :disable="disabledSending" 
            />
          </q-card-actions>
        </template>
        <q-card-section v-else>
          <q-banner class="q-py-md yellow-banner rounded-borders">
            <div class="q-mb-md">
              <div class="text-h6">{{ $t('statements.InviteDialog.slotsAreNotAvailable') }}</div>
              <div class="text-subtitle2">{{ $t('statements.InviteDialog.pleaseGenerateSlotsForService') }}</div>
            </div>
            <template v-slot:action>
              <q-btn
                flat
                to="/tickets"
                :label="$t('statements.InviteDialog.goToSchedule')"
              />
            </template>
          </q-banner>
        </q-card-section>
        <q-inner-loading :showing="loading">
          <q-spinner-gears color="primary" size="50px" />
        </q-inner-loading>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import get from 'lodash/get';
import { Vue, Prop, Component } from 'vue-property-decorator';
import { BaseCardCommon } from '@/interfaces';
import { UserTaskListItem, WorkflowServiceApi } from '@openapi/wf';
import { Application } from '@interfaces/entities/Application';
import { notifyError, notifySuccess } from '@utils/notify';
import ButtonSettings from '@interfaces/entities/ButtonSettings';
import { convertDateFormat, DateFormat, parseDateFromString, } from '@utils/format-date';
import preorderService from '@services/preorder';
import { PastGatewayParams } from '@state/modules/mz/gateway';

const wfApi = new WorkflowServiceApi();

@Component({
  methods: {
    get,
   },
})
export default class CreatingInviteDialog extends Vue {
  @Prop({}) private common: BaseCardCommon;
  @Prop({}) private model: Application;
  @Prop({}) private userTask: UserTaskListItem;
  @Prop({}) private row: any;
  @Prop({}) private disableAllButtons: boolean;

  private firstSlotDate: Date = new Date('');
  private lastSlotDate: Date = new Date('');

  private loading = true;
  private dialog = false;
  private eventDate = '';
  private startDate = '';
  private endDate = '';
  private areaId = '';
  private inviteComment = '';
  private organizationId = '';
  private disabledSending = false;
  private receivedareaId = false

  get serviceId() {
    return this.$store.getters['registryService/services/servicesCard']?.targetId;
  }

  get slotsAvailable(): boolean {
    return !isNaN(this.firstSlotDate.getTime()) && !isNaN(this.lastSlotDate.getTime());
  }

 async mounted(): Promise<void> {
    this.loading = true;
    await this.getOrganization(); 
    await this.getAreaId();
    await this.getAvailableDateRange();
    this.loading = false;
  }

  openDialogWindow(): void {
     this.dialog = true;
  }

  closeDialogWindow(): void {
     this.dialog = false;
  }

  inviteToMeeting(): void {
    this.closeDialogWindow();
    let invitationRequest: PastGatewayParams = {
      taskId: String(this.userTask.userTask?.taskId),
      organizationId: this.organizationId,
      areaId: this.areaId,
      comment: this.inviteComment,
      orderId: String(this.model.common.orderId),
    }
    if (this.startDate && this.endDate) {
      invitationRequest.startDate = convertDateFormat(this.startDate, DateFormat.date, DateFormat.invertedDate);
      invitationRequest.endDate = convertDateFormat(this.endDate, DateFormat.date, DateFormat.invertedDate);
    }
    if (this.eventDate) {
      invitationRequest.eventDate = convertDateFormat(this.eventDate, DateFormat.invertedDate, DateFormat.backend);
    }

    this.$store
        .dispatch('mz/gateway/eventServiceRequest', invitationRequest)
        .then(() => {
          notifySuccess(this.$t('statements.inviteSentSuccess').toString());
        })
        .catch(() => {
          notifyError(this.$t('statements.inviteSentFailed').toString());
        });
  }

  async getAreaId(): Promise<void> {
    try {
      const organizationFromPreorder = await preorderService.getOrgSchedule(this.organizationId);
      const schedule = organizationFromPreorder.orgSchedules?.find(({services}) => {
        return services && !!services.find(({serviceId}) => this.serviceId === serviceId);
      });

      this.organizationId = String(organizationFromPreorder.orgIdFromMS);
      this.areaId = schedule?.areaId || '';
      this.receivedareaId = true;
    } catch(error) {
      console.error('[statements card][invite dialog] schedule has not found');
    }
  }
 
 async getOrganization(): Promise<void> {
    const currentUser = this.$store.getters['oidcClient/currentUser'];
    const organization = await this.$store.dispatch(
      'idm/organizations/getOrganization',
      { id: currentUser.domain_id }
    );

    this.organizationId = organization.ogrn;
  }
  
  async getAvailableDateRange(): Promise<void> {
    try {
      const slots = await preorderService.getSlots({
        organizationId: this.organizationId,
        serviceId: this.serviceId,
      });
      this.firstSlotDate = this.getClearedDate(slots[0]?.visitTime);
      this.lastSlotDate = this.getClearedDate(slots.pop()?.visitTime);
      this.startDate = convertDateFormat(this.firstSlotDate, '', DateFormat.date);
      this.endDate = convertDateFormat(this.lastSlotDate, '', DateFormat.date);
    } catch(error) {
      notifyError(this.$t('statements.InviteDialog.slotsHaveNotFound').toString());
    }
  }

  getClearedDate(dateTimeString = ''): Date {
    const [dateString] = dateTimeString.match(/\d{4}-\d{2}-\d{2}/) || [];
    return parseDateFromString(dateString, DateFormat.invertedDate) || new Date('');
  }

  convertDate(date: Date, defaultDate: string): string {
    if (isNaN(date.getTime())) {
      return defaultDate;
    }
    return convertDateFormat(date, '', DateFormat.date)
  }

  testAtreaId(areaId: string): boolean | string {
    if (/[$%&*+\-=@#!\\\/|]/g.test(areaId)) {
      return this.$t('statements.InviteDialog.wrongAreaId').toString();
    }

    if (!areaId){
      this.disabledSending = true;
      return this.$t('statements.InviteDialog.emptyAreaId').toString();
    } else {
      this.disabledSending = false;
    }

    return true;
  }

  testDateRange(dateString: string): boolean | string {
    const date = parseDateFromString(dateString, DateFormat.date);

    if (!date || isNaN(date.getTime())) {
      return this.$t('statements.InviteDialog.wrongDate').toString();
    }

    if (date < this.firstSlotDate) {
      return this.$t('statements.InviteDialog.dateLessThanAvailable').toString();
    }

    if (date > this.lastSlotDate) {
      return this.$t('statements.InviteDialog.dateFurcherThanAvailable').toString();
    }

    return true;
  }
}
</script>
    

