import { useMutation, useQuery } from '@tanstack/react-query';

import { PARTICIPANT_EXITS_ERROR, UNAUTHORIZED_UNIT_ERROR } from '../constants/custom';
import api from '../services/api';
import {
  EventFunctionAllGeneralPayload,
  EventGeneralInsertPayload,
  EventGeneralUpdateReportPayload,
  ParticipantGeneralAllResponse,
  ParticipantGeneralInsertNewPayload,
  ParticipantGeneralUpdatePayload,
} from '../services/api/APIS/Events/types';
import { showFeedback } from '../services/feedback/showFeedback';
import { useRegionAllGet } from './useCamps';
import { usePhotos } from './useCongress';
import { useHasPersonAccess } from './usePerson';

export const useEventGeneralStateAllGet = (token: string, disabled = false) => {
  return useQuery(
    ['general-state-list', [token]],
    () => api.events.eventGeneralStatesAllGet(token),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventGeneralTypeAllGet = (token: string, disabled = false) => {
  return useQuery(['general-type-list', [token]], () => api.events.eventGeneralTypeAllGet(token), {
    enabled: !!token && !disabled,
  });
};

export const useEventGeneralScopeAllGet = (token: string, disabled = false) => {
  return useQuery(
    ['general-scope-list', [token]],
    () => api.events.eventGeneralScopeAllGet(token),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventFilter = (token: string) => {
  const { data: states, isLoading: isStatesLoading } = useEventGeneralStateAllGet(token);
  const { data: types, isLoading: isTypesLoading } = useEventGeneralTypeAllGet(token);
  const { data: scopes, isLoading: isScopesLoading } = useEventGeneralScopeAllGet(token);

  const isLoading = isStatesLoading || isTypesLoading || isScopesLoading;

  return {
    states,
    types,
    scopes,
    isLoading,
  };
};

export const useEventGeneralAllGet = (
  token: string,
  isFuture: string,
  year: string,
  isRelation: string,
  isChildDirect: string,
  isChildUnit: string,
  typeId: string,
  stateId: string,
  scopeId: string,
  disabled = false,
) => {
  return useQuery(
    [
      'general-list',
      [token, isFuture, year, isRelation, isChildDirect, isChildUnit, typeId, stateId, scopeId],
    ],
    () =>
      api.events.eventGeneralAllGet(
        token,
        isFuture,
        year,
        isRelation,
        isChildDirect,
        isChildUnit,
        typeId,
        stateId,
        scopeId,
      ),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventGeneralDetailGet = (token: string, eventId: string, disabled = false) => {
  return useQuery(
    ['general-detail', [token, eventId]],
    () => api.events.eventGeneralDetailGet(token, eventId),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventDetail = (token: string, eventId: string, disabled = false) => {
  const { data: event, isLoading, refetch } = useEventGeneralDetailGet(token, eventId, disabled);

  const detail = {
    ...event,
    isClosed: ['approvedLeader', 'approvedParent'].indexOf(event?.stateId || '') !== -1,
    isEditable: ['approvedLeader', 'approvedParent'].indexOf(event?.stateId || '') === -1,
  };
  return {
    detail,
    isLoading,
    refetch,
  };
};

export const useEventFunctionAllGeneralGet = (token: string, eventId: string, disabled = false) => {
  return useQuery(
    ['function-list', [token, eventId]],
    () => api.events.eventFunctionAllGeneralGet(token, eventId),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventGeneralUpdateFunction = (
  token: string,
  eventId: string,
  refetchFunctions: () => void,
  goBack?: () => void,
) => {
  return useMutation(
    ['event-date-delete', token, eventId],
    (payload: EventFunctionAllGeneralPayload[]) =>
      api.events.eventGeneralUpdateFunctionPost(token, eventId, payload),
    {
      onSuccess: () => {
        refetchFunctions();
        goBack && goBack();
        showFeedback({
          title: 'Složení týmu bylo úspěšně upraveno.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při upravování týmu došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useParticipantGeneralAllGet = (token: string, eventId: string, disabled = false) => {
  return useQuery(
    ['general-participant-all', [token, eventId]],
    () => api.events.participantGeneralAllGet(token, eventId),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useParticipants = (token: string, eventId: string) => {
  const {
    data: participants,
    isFetching: isParticipantsLoading,
    refetch: refetchList,
  } = useParticipantGeneralAllGet(token, eventId);
  const photos = usePhotos(token, participants || []);
  const personAccesses = useHasPersonAccess(token, participants || []);

  const list = participants?.map((item: ParticipantGeneralAllResponse) => {
    const photo = photos.map(item => item.data).find(logoItem => logoItem?.id === item.personId);
    const hasPersonAccess = personAccesses
      .map(item => item.data)
      .find(accessItem => accessItem?.id === item.personId)?.hasAccess;
    return {
      ...item,
      photo: photo?.photoContent || '',
      hasPersonAccess,
    };
  });

  const isLoading = isParticipantsLoading || personAccesses.some(item => item.isLoading);

  return { list, isLoading, refetchList };
};

export const useParticipantGeneralDeletePost = (token: string, refetchParticipants: () => void) => {
  return useMutation(
    ['participant-general-delete', token],
    (participantId: string) => api.events.participantGeneralDeletePost(token, participantId),
    {
      onSuccess: () => {
        refetchParticipants();
        showFeedback({
          title: 'Účastník byl úspěšně odebrán z akce.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při mazání účastníka došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useParticipantGeneralUpdatePost = (
  token: string,
  participantId: string,
  refetchParticipants: () => void,
  goBack: () => void,
) => {
  return useMutation(
    ['participant-general-update', token, participantId],
    (payload: ParticipantGeneralUpdatePayload) =>
      api.events.participantGeneralUpdatePost(token, participantId, payload),
    {
      onSuccess: () => {
        refetchParticipants();
        goBack();
        showFeedback({
          title: 'Účastník byl úspěšně upraven.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při úpravě účastníka došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useParticipantGeneralInsertPost = (
  token: string,
  eventId: string,
  refetchParticipants: () => void,
  goBack?: () => void,
) => {
  return useMutation(
    ['participant-general-insert', token, eventId],
    (personId: string) => api.events.participantGeneralInsertPost(token, eventId, personId),
    {
      onSuccess: () => {
        refetchParticipants();
        goBack && goBack();
        showFeedback({
          title: `Účastní${goBack ? 'ci byly úspěšně přidáni.' : 'k byl úspěšně přidán.'}`,
          type: 'success',
        });
      },
      onError: (err: string) => {
        let message =
          'Při přidání účastníka došlo k chybě. Zkontrolujte prosím vaše internetové připojení.';
        if (err.includes(PARTICIPANT_EXITS_ERROR)) {
          message = 'Účastník již je přidán v akci.';
        }
        showFeedback({
          title: message,
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useParticipantGeneralInsertNewPost = (
  token: string,
  eventId: string,
  refetchParticipants: () => void,
  goBack: () => void,
) => {
  return useMutation(
    ['participant-general-insert', token, eventId],
    (payload: ParticipantGeneralInsertNewPayload) =>
      api.events.participantGeneralInsertNewPost(token, eventId, payload),
    {
      onSuccess: () => {
        refetchParticipants();
        goBack();
        showFeedback({
          title: 'Účastník byl úspěšně přidán.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při přidání účastníka došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventEventStatisticAllEventGeneral = (
  token: string,
  eventId: string,
  disabled = false,
) => {
  return useQuery(
    ['event-statistic-all', [token, eventId]],
    () => api.events.eventStatisticAllEventGeneralGet(token, eventId),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEventGeneralUpdateStatisticAutoComputedPost = (
  token: string,
  eventId: string,
  refetch: () => void,
) => {
  return useMutation(
    ['participant-stats-auto-computed', token, eventId],
    (value: boolean) =>
      api.events.eventGeneralUpdateStatisticAutoComputedPost(token, eventId, value),
    {
      onSuccess: () => {
        refetch();
        showFeedback({
          title: 'Automatické počítání statistik bylo upraveno.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při upravování automatického počítání statistik došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventGeneralUpdateStatePost = (
  token: string,
  eventId: string,
  refetch: () => void,
) => {
  return useMutation(
    ['event-general-state', token, eventId],
    (isClosed: boolean) =>
      isClosed
        ? api.events.eventGeneralUpdateOpenPost(token, eventId)
        : api.events.eventGeneralUpdateClosePost(token, eventId),
    {
      onSuccess: () => {
        refetch();
        showFeedback({
          title: 'Stav akce byl upraven.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při uzavírání stavu akce došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventGeneralUpdateReportPost = (
  token: string,
  eventId: string,
  refetch: () => void,
  goBack: () => void,
) => {
  return useMutation(
    ['event-general-close', token, eventId],
    (payload: EventGeneralUpdateReportPayload) =>
      api.events.eventGeneralUpdateReportPost(token, eventId, payload),
    {
      onSuccess: () => {
        refetch();
        goBack();
        showFeedback({
          title: 'Zpráva akce byla upravena.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při upravení zprávy akce došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventEdit = (token: string) => {
  const { data: types, isLoading: isTypesLoading } = useEventGeneralTypeAllGet(token);
  const { data: scopes, isLoading: isScopesLoading } = useEventGeneralScopeAllGet(token);
  const { data: regions, isLoading: isRegionsLoading } = useRegionAllGet(token);

  const isLoading = isTypesLoading || isScopesLoading || isRegionsLoading;

  return { types, scopes, regions, isLoading };
};

export const useEventAddPost = (
  token: string,
  goBack: () => void,
  refetchEvents: () => void,
  refetchEventDetail: () => void,
  eventId?: string,
) => {
  return useMutation(
    ['event-general-add', [token, eventId]],
    (payload: EventGeneralInsertPayload) => api.events.eventGeneralAdd(token, payload, eventId),
    {
      onSuccess: () => {
        if (eventId) {
          refetchEventDetail && refetchEventDetail();
        }
        refetchEvents();
        goBack();
        showFeedback({
          title: `Akce byla úspěšně ${eventId ? 'upravena' : 'přidána'}.`,
          type: 'success',
        });
      },
      onError: (err: string) => {
        showFeedback({
          title: err.includes(UNAUTHORIZED_UNIT_ERROR)
            ? 'Nemáte práva tvořit akce pod vybraným pořadatelem.'
            : `Při ${
                eventId ? 'upravení' : 'přidání'
              } akce došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventDelete = (token: string, goBack: () => void, refetchEvents: () => void) => {
  return useMutation(
    ['event-general-delete', [token]],
    (eventId: string) => api.events.eventGeneralDelete(token, eventId),
    {
      onSuccess: () => {
        refetchEvents();
        goBack();
        showFeedback({
          title: `Akce byla úspěšně smazána.`,
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title: `Při mazání akce došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};
