import { defineComponent, inject, ref, type Ref, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import useVuelidate from '@vuelidate/core';
import { required, helpers } from '@vuelidate/validators';

import StrutturaService from '../struttura/struttura.service';
import DisponibilitaService from '../disponibilita/disponibilita.service';
import { type IStruttura } from '@/shared/model/struttura.model';
import { type IDisponibilita, Disponibilita } from '@/shared/model/disponibilita.model';
import { GiornoSettimana } from '@/shared/model/enumerations/giorno-settimana.model';
import { TipoDisponibilita } from '@/shared/model/enumerations/tipo-disponibilita.model';
import { useAlertService } from '@/shared/alert/alert.service';

export default defineComponent({
  compatConfig: { MODE: 3 },
  name: 'StrutturaDisponibilitaConfig',
  setup() {
    const route = useRoute();
    const router = useRouter();
    const { t: t$ } = useI18n();

    // Services
    const strutturaService = inject('strutturaService', () => new StrutturaService());
    const disponibilitaService = inject('disponibilitaService', () => new DisponibilitaService());
    const alertService = inject('alertService', () => useAlertService(), true);

    // State
    const struttura: Ref<IStruttura | null> = ref(null);
    const disponibilita: Ref<IDisponibilita> = ref(new Disponibilita());
    const disponibilitas: Ref<IDisponibilita[]> = ref([]);
    const isSaving = ref(false);
    const isLoading = ref(true);

    // Enums
    const giornoSettimanaValues = ref(Object.keys(GiornoSettimana));
    const tipoDisponibilitaValues = ref(Object.keys(TipoDisponibilita));

    // Custom validator: exactly one of dataSpecifica OR giornoSettimana
    const exactlyOne = helpers.withMessage(t$('smartbookingApp.disponibilita.validation.exactlyOneRequired'), (value, siblings) => {
      const hasData = !!siblings.dataSpecifica;
      const hasGiorno = !!siblings.giornoSettimana;
      return (hasData && !hasGiorno) || (!hasData && hasGiorno);
    });

    // Validation rules
    const validationRules = {
      tipo: { required },
      orarioInizio: { required },
      orarioFine: { required },
      dataSpecifica: { exactlyOne },
      giornoSettimana: {},
      note: {},
    };

    const v$ = useVuelidate(validationRules, disponibilita);

    // Initialize with defaults
    disponibilita.value.tipo = 'CHIUSURA';

    // Load data
    const loadData = async () => {
      const strutturaId = Number(route.params.strutturaId);
      try {
        struttura.value = await strutturaService().find(strutturaId);
        disponibilita.value.struttura = struttura.value;

        // Load disponibilitas and filter by struttura
        const dispRes = await disponibilitaService().retrieve();
        disponibilitas.value = dispRes.data.filter(d => d.struttura?.id === strutturaId);

        isLoading.value = false;
      } catch (error) {
        alertService().showHttpError(error.response);
      }
    };

    const save = async () => {
      await v$.value.$validate();
      if (v$.value.$invalid) return;

      isSaving.value = true;
      try {
        await disponibilitaService().create(disponibilita.value);
        alertService().showSuccess(t$('smartbookingApp.disponibilita.created', { param: '' }));

        // Reset form
        disponibilita.value = new Disponibilita();
        disponibilita.value.struttura = struttura.value;
        disponibilita.value.tipo = 'CHIUSURA';
        v$.value.$reset();

        // Reload list
        await loadData();
      } catch (error) {
        alertService().showHttpError(error.response);
      } finally {
        isSaving.value = false;
      }
    };

    const cancel = () => {
      router.push({ name: 'Struttura' });
    };

    const deleteDisponibilita = async (id: number) => {
      try {
        await disponibilitaService().delete(id);
        alertService().showInfo(t$('smartbookingApp.disponibilita.deleted', { param: id }));
        await loadData();
      } catch (error) {
        alertService().showHttpError(error.response);
      }
    };

    onMounted(() => {
      loadData();
    });

    return {
      struttura,
      disponibilita,
      disponibilitas,
      isSaving,
      isLoading,
      giornoSettimanaValues,
      tipoDisponibilitaValues,
      v$,
      save,
      cancel,
      deleteDisponibilita,
      t$,
    };
  },
});
