import { type Ref, computed, defineComponent, inject, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';

import { useVuelidate } from '@vuelidate/core';

import ConfermaService from '@/entities/conferma/conferma.service';
import StrutturaService from '@/entities/struttura/struttura.service';
import UtenteAppService from '@/entities/utente-app/utente-app.service';
import { useAlertService } from '@/shared/alert/alert.service';
import { useDateFormat, useValidation } from '@/shared/composables';
import { type IConferma } from '@/shared/model/conferma.model';
import { StatoPrenotazione } from '@/shared/model/enumerations/stato-prenotazione.model';
import { type IPrenotazione, Prenotazione } from '@/shared/model/prenotazione.model';
import { type IStruttura } from '@/shared/model/struttura.model';
import { type IUtenteApp } from '@/shared/model/utente-app.model';

import PrenotazioneService from './prenotazione.service';

export default defineComponent({
  name: 'PrenotazioneUpdate',
  setup() {
    const prenotazioneService = inject('prenotazioneService', () => new PrenotazioneService());
    const alertService = inject('alertService', () => useAlertService(), true);

    const prenotazione: Ref<IPrenotazione> = ref(new Prenotazione());

    const confermaService = inject('confermaService', () => new ConfermaService());

    const confermas: Ref<IConferma[]> = ref([]);

    const utenteAppService = inject('utenteAppService', () => new UtenteAppService());

    const utenteApps: Ref<IUtenteApp[]> = ref([]);

    const strutturaService = inject('strutturaService', () => new StrutturaService());

    const strutturas: Ref<IStruttura[]> = ref([]);
    const statoPrenotazioneValues: Ref<string[]> = ref(Object.keys(StatoPrenotazione));
    const isSaving = ref(false);
    const currentLanguage = inject('currentLanguage', () => computed(() => navigator.language ?? 'it'), true);

    const route = useRoute();
    const router = useRouter();

    const previousState = () => router.go(-1);

    const retrievePrenotazione = async prenotazioneId => {
      try {
        const res = await prenotazioneService().find(prenotazioneId);
        res.oraInizio = new Date(res.oraInizio);
        res.oraFine = new Date(res.oraFine);
        prenotazione.value = res;
      } catch (error) {
        alertService.showHttpError(error.response);
      }
    };

    if (route.params?.prenotazioneId) {
      retrievePrenotazione(route.params.prenotazioneId);
    }

    const initRelationships = () => {
      confermaService()
        .retrieve()
        .then(res => {
          confermas.value = res.data;
        });
      utenteAppService()
        .retrieve()
        .then(res => {
          utenteApps.value = res.data;
        });
      strutturaService()
        .retrieve()
        .then(res => {
          strutturas.value = res.data;
        });
    };

    initRelationships();

    const { t: t$ } = useI18n();
    const validations = useValidation();
    const validationRules = {
      oraInizio: {},
      oraFine: {},
      stato: {},
      motivoEvento: {},
      numeroPartecipanti: {},
      noteUtente: {},
      conferma: {},
      utente: {},
      struttura: {},
    };
    const v$ = useVuelidate(validationRules, prenotazione as any);
    v$.value.$validate();

    return {
      prenotazioneService,
      alertService,
      prenotazione,
      previousState,
      statoPrenotazioneValues,
      isSaving,
      currentLanguage,
      confermas,
      utenteApps,
      strutturas,
      v$,
      ...useDateFormat({ entityRef: prenotazione }),
      t$,
    };
  },
  created(): void {},
  methods: {
    save(): void {
      this.isSaving = true;
      if (this.prenotazione.id) {
        this.prenotazioneService()
          .update(this.prenotazione)
          .then(param => {
            this.isSaving = false;
            this.previousState();
            this.alertService.showInfo(this.t$('smartbookingApp.prenotazione.updated', { param: param.id }));
          })
          .catch(error => {
            this.isSaving = false;
            this.alertService.showHttpError(error.response);
          });
      } else {
        this.prenotazioneService()
          .create(this.prenotazione)
          .then(param => {
            this.isSaving = false;
            this.previousState();
            this.alertService.showSuccess(this.t$('smartbookingApp.prenotazione.created', { param: param.id }).toString());
          })
          .catch(error => {
            this.isSaving = false;
            this.alertService.showHttpError(error.response);
          });
      }
    },
  },
});
