import { type Ref, computed, defineComponent, inject, onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';

import { useAlertService } from '@/shared/alert/alert.service';
import { useDateFormat } from '@/shared/composables';
import { type IConferma } from '@/shared/model/conferma.model';
import { TipoConferma } from '@/shared/model/enumerations/tipo-conferma.model';
import { type IPrenotazione } from '@/shared/model/prenotazione.model';
import { Authority } from '@/shared/security/authority';
import { useAccountStore } from '@/shared/config/store/account-store';

import ConfermaService from '../conferma/conferma.service';
import PrenotazioneService from './prenotazione.service';

export default defineComponent({
  name: 'Prenotazione',
  setup() {
    const { t: t$ } = useI18n();
    const dateFormat = useDateFormat();
    const prenotazioneService = inject('prenotazioneService', () => new PrenotazioneService());
    const confermaService = inject('confermaService', () => new ConfermaService());
    const alertService = inject('alertService', () => useAlertService(), true);
    const accountStore = useAccountStore();

    const itemsPerPage = ref(20);
    const queryCount: Ref<number> = ref(null);
    const page: Ref<number> = ref(1);
    const propOrder = ref('id');
    const reverse = ref(false);
    const totalItems = ref(0);

    const prenotaziones: Ref<IPrenotazione[]> = ref([]);
    const isFetching = ref(false);

    // Role-based helpers
    const account = computed(() => accountStore.account);
    const isIncaricato = computed(() => account.value?.authorities?.includes(Authority.INCARICATO) ?? false);

    // ROLE_INCARICATO: split list into pending (no conferma) and completed (with conferma)
    const prenotazioniPendenti = computed(() => prenotaziones.value.filter(p => !p.conferma));
    const prenotazioniCompletate = computed(() => prenotaziones.value.filter(p => !!p.conferma));

    // "Prendi in carico" modal state
    const showPrendiInCaricoModal = ref(false);
    const selectedPrenotazione: Ref<IPrenotazione | null> = ref(null);
    const confermaForm = ref<{ tipoConferma: string; motivoConferma: string }>({
      tipoConferma: '',
      motivoConferma: '',
    });
    const isSubmittingConferma = ref(false);

    const clear = () => {
      page.value = 1;
    };

    const sort = (): Array<any> => {
      const result = [`${propOrder.value},${reverse.value ? 'desc' : 'asc'}`];
      if (propOrder.value !== 'id') {
        result.push('id');
      }
      return result;
    };

    const retrievePrenotaziones = async () => {
      isFetching.value = true;
      try {
        const paginationQuery = {
          page: page.value - 1,
          size: itemsPerPage.value,
          sort: sort(),
        };
        const res = await prenotazioneService().retrieve(paginationQuery);
        totalItems.value = Number(res.headers['x-total-count']);
        queryCount.value = totalItems.value;
        prenotaziones.value = res.data;
      } catch (err) {
        alertService.showHttpError(err.response);
      } finally {
        isFetching.value = false;
      }
    };

    const handleSyncList = () => {
      retrievePrenotaziones();
    };

    onMounted(async () => {
      await retrievePrenotaziones();
    });

    const removeId: Ref<number> = ref(null);
    const removeEntity = ref<any>(null);
    const prepareRemove = (instance: IPrenotazione) => {
      removeId.value = instance.id;
      removeEntity.value.show();
    };
    const closeDialog = () => {
      removeEntity.value.hide();
    };
    const removePrenotazione = async () => {
      try {
        await prenotazioneService().delete(removeId.value);
        const message = t$('smartbookingApp.prenotazione.deleted', { param: removeId.value }).toString();
        alertService.showInfo(message, { variant: 'danger' });
        removeId.value = null;
        retrievePrenotaziones();
        closeDialog();
      } catch (error) {
        alertService.showHttpError(error.response);
      }
    };

    const prendiInCarico = (prenotazione: IPrenotazione) => {
      selectedPrenotazione.value = prenotazione;
      confermaForm.value = { tipoConferma: '', motivoConferma: '' };
      showPrendiInCaricoModal.value = true;
    };

    const closePrendiInCaricoModal = () => {
      showPrendiInCaricoModal.value = false;
      selectedPrenotazione.value = null;
    };

    const submitConferma = async () => {
      if (!selectedPrenotazione.value || !confermaForm.value.tipoConferma) return;
      isSubmittingConferma.value = true;
      try {
        const newConferma: IConferma = {
          id: selectedPrenotazione.value.id,
          tipoConferma: confermaForm.value.tipoConferma as keyof typeof TipoConferma,
          motivoConferma: confermaForm.value.motivoConferma || null,
        };
        await confermaService().create(newConferma);
        alertService.showInfo(t$('smartbookingApp.prenotazione.prendiInCarico.success').toString());
        closePrendiInCaricoModal();
        await retrievePrenotaziones();
      } catch (error) {
        alertService.showHttpError(error.response);
      } finally {
        isSubmittingConferma.value = false;
      }
    };

    const changeOrder = (newOrder: string) => {
      if (propOrder.value === newOrder) {
        reverse.value = !reverse.value;
      } else {
        reverse.value = false;
      }
      propOrder.value = newOrder;
    };

    watch([propOrder, reverse], async () => {
      if (page.value === 1) {
        await retrievePrenotaziones();
      } else {
        clear();
      }
    });

    watch(page, async () => {
      await retrievePrenotaziones();
    });

    return {
      prenotaziones,
      handleSyncList,
      isFetching,
      retrievePrenotaziones,
      clear,
      ...dateFormat,
      removeId,
      removeEntity,
      prepareRemove,
      closeDialog,
      removePrenotazione,
      itemsPerPage,
      queryCount,
      page,
      propOrder,
      reverse,
      totalItems,
      changeOrder,
      t$,
      // Role-based
      isIncaricato,
      prenotazioniPendenti,
      prenotazioniCompletate,
      // Prendi in carico modal
      showPrendiInCaricoModal,
      selectedPrenotazione,
      confermaForm,
      isSubmittingConferma,
      prendiInCarico,
      closePrendiInCaricoModal,
      submitConferma,
    };
  },
});
