import { Controller, useForm } from 'react-hook-form';
import { useMutation, useQueryClient } from 'react-query';
import { useNavigate, useParams } from 'react-router';

import { AxiosResponse } from 'axios';

import useSnackbar from '@material-hu/components/design-system/Snackbar';
import useRegionQuery from 'src/hooks/queryHooks/useRegion';
import useGeneralError from 'src/hooks/useGeneralError';
import * as sitesService from 'src/services/sitesService';
import { Site, SiteFormFields, SiteParams } from 'src/types/regions';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { PaginatedResponse } from 'src/utils/tableUtils';
import { validateCoordinatesRule } from 'src/utils/validation';

import CreationLayout from '../../components/CreationLayout';
import DetailsStep from '../../components/DetailsStep';
import PeopleStep from '../../components/PeopleStep';
import { CollabSelection } from '../../constants';
import { getSitesListResponse, regionKeys } from '../../queries';
import { regionRoutes } from '../../routes';
import { truncateSiteName } from '../../utils';
import LocationSelector from '../components/LocationSelector';

const SiteCreate = () => {
  const { t } = useLokaliseTranslation('regions_sites');
  const navigate = useNavigate();
  const showGeneralError = useGeneralError();
  const { enqueueSnackbar } = useSnackbar();
  const params = useParams();
  const regionId = parseInt(params.id || '0');
  const queryClient = useQueryClient();

  const { data: regionData } = useRegionQuery(regionId, {
    enabled: !!regionId,
  });

  const form = useForm<SiteFormFields>({
    defaultValues: {
      name: '',
      body: '',
      location: undefined,
      tolerance: 100,
      userIds: [],
      regionsUserMode: CollabSelection.NONE,
    },
    mode: 'onChange',
  });

  const mutation = useMutation(
    () => {
      const site = form.getValues();
      const location = {
        address: truncateSiteName(site.location!.title),
        latitude: site.location!.lat,
        longitude: site.location!.lng,
        tolerance: site.tolerance,
      };
      const payload: Partial<SiteParams> = {
        name: site.name,
        location,
      };
      if (site.body.length > 0) {
        payload.body = site.body;
      }
      if (site.regionsUserMode === CollabSelection.ALL_USERS) {
        payload.userIds = null;
        payload.regionsUserMode = site.regionsUserMode;
      } else if (site.regionsUserMode === CollabSelection.TARGETED_USERS) {
        payload.userIds = site.userIds;
        payload.regionsUserMode = site.regionsUserMode;
      }
      return sitesService.createSite(regionId, payload as SiteParams);
    },
    {
      onSuccess: response => {
        enqueueSnackbar({
          title: t('create_success'),
          variant: 'success',
        });
        if (response?.data) {
          if (getSitesListResponse(regionId) !== undefined) {
            const oldData = queryClient.getQueryData<
              AxiosResponse<PaginatedResponse<Site>>
            >(regionKeys.sites(regionId));
            if (oldData) {
              queryClient.setQueryData<AxiosResponse<PaginatedResponse<Site>>>(
                regionKeys.sites(regionId),
                {
                  ...oldData,
                  data: {
                    ...oldData.data,
                    items: [response.data, ...oldData.data.items],
                  },
                },
              );
            }
          }
        }
        navigate(regionRoutes.regionSites(regionId));
      },
      onError: err => {
        showGeneralError(err, t('create_error'));
      },
    },
  );

  const steps = [
    {
      label: t('general_data'),
      Component: <DetailsStep />,
    },
    {
      label: t('LOCATION'),
      Component: (
        <Controller
          render={() => (
            <LocationSelector
              mapId={import.meta.env.VITE_GOOGLE_MAPS_SITES_MAP_ID}
            />
          )}
          name="location"
          control={form.control}
          rules={{
            required: true,
            validate: validateCoordinatesRule,
          }}
        />
      ),
      sxContainerWrapper: {
        flex: 1,
        p: 0,
      },
      sxContainer: {
        flex: 1,
        maxWidth: 'unset',
      },
    },
    {
      label: t('ASSIGNMENTS'),
      sublabel: t('PEOPLE_SUBTITLE'),
      Component: (
        <PeopleStep
          regionId={regionId}
          totalUsers={regionData?.userIds || []}
        />
      ),
    },
  ];

  const navigateBack = () => {
    navigate(regionRoutes.regionSites(regionId));
  };

  return (
    <CreationLayout
      createMutation={mutation}
      form={form}
      title={t('NEW_SITE')}
      handleBackNavigation={navigateBack}
      steps={steps}
    />
  );
};

export default SiteCreate;
