import { useCallback } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useMutation } from '@apollo/client';
import { useQueryWithPreviousData } from 'lib/apollo';
import { APPLY_FILTERS, FILTERS } from 'components/filters/schema';
import {
  ApplyFiltersMutation,
  ApplyFiltersMutationVariables,
  FiltersQuery,
  FiltersQueryVariables,
} from 'types/graphql';

import { useUrlSearchParams } from 'hooks/useUrlSearchParams';

import { Box, Spinner } from 'components/common';
import { SidebarCloseButton } from 'components/sidebar/Sidebar';
import { FiltersForm, HandleSubmit } from 'components/filters/FiltersForm';

import { PATHS as ALLIANCE } from '../index';

import { assignParams } from 'components/router/assignParams';

export const AllianceFiltersPanel = () => {
  const location = useLocation();
  const navigate = useNavigate();

  const { allianceId } = useParams();
  const { [ALLIANCE.collection]: collectionId, [ALLIANCE.set]: setId } =
    useUrlSearchParams();

  const filtersQuery = useQueryWithPreviousData<
    FiltersQuery,
    FiltersQueryVariables
  >(FILTERS, {
    variables: {
      allianceId,
      collectionId,
      setId: setId || '-1',
      filtered: Boolean(setId),
    },
  });

  const data = filtersQuery.data;

  const [applyFilters, mutation] = useMutation<
    ApplyFiltersMutation,
    ApplyFiltersMutationVariables
  >(APPLY_FILTERS);

  const handleSubmit: HandleSubmit = useCallback(
    async (data) => {
      try {
        const res = await applyFilters({
          variables: {
            allianceId: !collectionId ? allianceId : undefined,
            sourceId: collectionId || undefined,
            input: data,
          },
        });

        const set = res?.data?.set;

        if (set?.id) {
          navigate(
            {
              ...location,
              search: assignParams(location.search, (s) => {
                s.set(ALLIANCE.set, set.id);
              }),
            },
            { replace: true }
          );
        }
      } catch (error) {
        console.error(error);
      }
    },
    [applyFilters, allianceId, collectionId, navigate, location]
  );

  const resetUrlParams = useCallback(() => {
    if (setId) {
      navigate(
        {
          ...location,
          search: assignParams(location.search, (s) => {
            s.delete(ALLIANCE.set);
          }),
        },
        { replace: true }
      );
    }
  }, [navigate, location, setId]);

  const closeSidebar = () => {
    navigate(
      {
        ...location,
        search: assignParams(location.search, (s) => {
          s.delete(ALLIANCE.set);
          s.delete(ALLIANCE.filter);
        }),
      },
      { replace: true }
    );
  };

  return (
    <div className="flex flexColumn">
      <Box
        flex="none"
        height={48}
        display="flex"
        align="center"
        justify="between"
        className="bg-white"
      >
        <Box className="bold fz16" paddingX={3}>
          Filter
        </Box>
        <SidebarCloseButton onClick={closeSidebar} />
      </Box>
      {data && (
        <FiltersForm
          filters={data.filters}
          initialState={data.appliedFilters}
          onSubmit={handleSubmit}
          onReset={resetUrlParams}
          loading={mutation.loading}
        />
      )}
      <Spinner show={!data && filtersQuery.loading} />
    </div>
  );
};
