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

import { FILTER_NONE, UNAUTHORIZED_ERROR } from '../constants/custom';
import api from '../services/api';
import {
  AdvertisingCategoryDetailResponse,
  MeetingDateDetailResponse,
  MembershipApplicationInsertResponse,
} from '../services/api/APIS/OrganizationUnit/types';
import { showFeedback } from '../services/feedback/showFeedback';

export const useUnitAdvertisingAccess = (token: string, unitId: string) => {
  const { data: advertising, isLoading } = useUnitAdvertisingCategoryAll(token, unitId);
  const hasAccess = useMemo(() => {
    if (!advertising) return false;
    return advertising !== UNAUTHORIZED_ERROR && advertising.unit !== '';
  }, [advertising, unitId]);

  return { hasAccess, isLoading };
};

export const useUnitAdvertising = (token: string, unitId: string) => {
  const { data: detail, isFetching: isDetailLoading } = useUnitAdvertisingDetail(token, unitId);
  const { data: categories, isFetching: isCategoriesLoading } = useUnitAdvertisingCategoryAll(
    token,
    unitId,
  );
  const { data: meetingDates, isFetching: isMeetingDatesLoading } =
    useUnitAdvertisingMeetingDateAll(token, unitId);

  const isLoading = isDetailLoading || isCategoriesLoading || isMeetingDatesLoading;

  const advertising = {
    ...detail,
    categories,
    meetingDates,
  };

  return { advertising, isLoading };
};

export const useUnitAdvertisingDetail = (token: string, unitId: string, disabled = false) => {
  return useQuery(
    ['unit-advertising-detail', [token, unitId]],
    () => api.organizationUnit.unitAdvertisingDetailGet(token, unitId),
    {
      enabled: !!token && !!unitId && !disabled,
    },
  );
};

export const useUnitAdvertisingDetailUpdate = (
  token: string,
  unitId: string,
  refetchAdvertising: () => void,
) => {
  return useMutation(
    ['unit-advertising-detail-update', [token, unitId]],
    (note: string) => api.organizationUnit.unitAdvertisingDetailUpdate(token, unitId, note),
    {
      onSuccess: () => {
        showFeedback({
          title: 'Poznámka byla upravena.',
          type: 'success',
        });
        refetchAdvertising();
      },
      onError: err => {
        showFeedback({
          title:
            'Při úpravě poznámky došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useUnitAdvertisingCategoryAll = (token: string, unitId: string, disabled = false) => {
  return useQuery(
    ['unit-advertising-category', [token, unitId]],
    () => api.organizationUnit.unitAdvertisingCategoryAllGet(token, unitId),
    {
      enabled: !!token && !!unitId && !disabled,
    },
  );
};

export const useUnitAdvertisingMeetingDateAll = (
  token: string,
  unitId: string,
  disabled = false,
) => {
  return useQuery(
    ['unit-advertising-meeting-date', [token, unitId]],
    () => api.organizationUnit.unitMeetingDateAllGet(token, unitId),
    {
      enabled: !!token && !!unitId && !disabled,
    },
  );
};

export const useUnitPlaces = (token: string, unitId: string) => {
  const { data: occupations, isLoading: isOccupationsLoading } = useUnitOccupationAll(
    token,
    unitId,
  );

  const { data: realties, isLoading: isRealtiesLoading } = useRealtyAll(token, unitId);

  const isLoading = isOccupationsLoading || isRealtiesLoading;

  const places = [
    { id: undefined, displayName: FILTER_NONE },
    ...(occupations?.map(occupation => {
      return {
        id: occupation.id,
        displayName: `${
          realties?.find(realty => realty.id === occupation.realtyId)?.displayName
        } - ${occupation.realtyType}`,
      };
    }) || []),
  ];

  return { places, isLoading };
};

export const useUnitOccupationAll = (token: string, unitId: string) => {
  return useQuery(
    ['unit-occupation-all', [token, unitId]],
    () => api.organizationUnit.unitOccupationAllGet(token, unitId),
    {
      enabled: !!token && !!unitId,
    },
  );
};

export const useRealtyAll = (token: string, unitId: string) => {
  return useQuery(
    ['realty-all', [token, unitId]],
    () => api.organizationUnit.unitRealtyAllGet(token, unitId),
    {
      enabled: !!token && !!unitId,
    },
  );
};

export const useUnitAdvertisingMeetingDate = (token: string, dateId: string) => {
  return useQuery(
    ['unit-advertising-meeting-date', [token, dateId]],
    () => api.organizationUnit.unitMeetingDateGet(token, dateId),
    {
      enabled: !!token && !!dateId,
    },
  );
};

export const useUnitAdvertisingMeetingDateAdd = (
  token: string,
  unitId: string,
  refetchMeetingDates: () => void,
  goBack: () => void,
  dateId?: string,
  refetchMeetingDate?: () => void,
) => {
  return useMutation(
    ['unit-advertising-meeting-date-add', [token, unitId, dateId]],
    (payload: MeetingDateDetailResponse) =>
      api.organizationUnit.unitMeetingDateAdd(token, unitId, payload, dateId),
    {
      onSuccess: () => {
        if (dateId) {
          refetchMeetingDate?.();
        }
        refetchMeetingDates();
        goBack();
        showFeedback({
          title: `Schůzka byla úspěšně ${dateId ? 'upravena' : 'přidána'}.`,
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title: `Při ${
            dateId ? 'upravení' : 'přidání'
          } schůzky došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useUnitAdvertisingMeetingDateDelete = (
  token: string,
  refetchMeetingDates: () => void,
  goBack: () => void,
) => {
  return useMutation(
    ['unit-advertising-meeting-date-delete', [token]],
    (dateId: string) => api.organizationUnit.unitMeetingDateDelete(token, dateId),
    {
      onSuccess: () => {
        refetchMeetingDates();
        goBack();
        showFeedback({
          title: 'Schůzka byla úspěšně smazána.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při mazání schůzky došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useUnitAdvertisingCategory = (token: string, categoryId: string) => {
  return useQuery(
    ['unit-advertising-category', [token, categoryId]],
    () => api.organizationUnit.unitAdvertisingCategoryGet(token, categoryId),
    {
      enabled: !!token && !!categoryId,
    },
  );
};

export const useUnitAdvertisingCategoryAdd = (
  token: string,
  unitId: string,
  refetchCategories: () => void,
  goBack: () => void,
  categoryId?: string,
  refetchCategory?: () => void,
) => {
  return useMutation(
    ['unit-advertising-category-add', [token, unitId, categoryId]],
    (payload: AdvertisingCategoryDetailResponse) =>
      api.organizationUnit.unitAdvertisingCategoryAdd(token, unitId, payload, categoryId),
    {
      onSuccess: () => {
        if (categoryId) {
          refetchCategory?.();
        }
        refetchCategories();
        goBack();
        showFeedback({
          title: `Kategorie byla úspěšně ${categoryId ? 'upravena' : 'přidána'}.`,
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title: `Při ${
            categoryId ? 'upravení' : 'přidání'
          } kategorie došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useUnitAdvertisingCategoryDelete = (
  token: string,
  refetchCategories: () => void,
  goBack: () => void,
) => {
  return useMutation(
    ['unit-advertising-category-delete', [token]],
    (categoryId: string) => api.organizationUnit.unitAdvertisingCategoryDelete(token, categoryId),
    {
      onSuccess: () => {
        refetchCategories();
        goBack();
        showFeedback({
          title: 'Kategorie byla úspěšně smazána.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title:
            'Při mazání kategorie došlo k chybě. Zkontrolujte prosím vaše internetové připojení.',
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useUnitApplicationAdd = (token: string, unitId: string, goBack: () => void) => {
  return useMutation(
    ['unit-application-add', [token, unitId]],
    (payload: MembershipApplicationInsertResponse) =>
      api.organizationUnit.unitApplicationInsert(token, unitId, payload),
    {
      onSuccess: () => {
        goBack();
        showFeedback({
          title: `Vaša e-přihláška byla odeslaná.`,
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title: `Při odesílání e-přihlášky došlo k chybě. Zkontrolujte prosím zadané hodnoty.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};
