import { ReactNode, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useMutation, useQuery } from 'react-query';
import { useNavigate } from 'react-router';
import { useSearchParams } from 'react-router-dom';

import { useModal } from '@material-hu/hooks/useModal';
import { IconList, IconSettings, TablerIcon } from '@material-hu/icons/tabler';

import Button from '@material-hu/components/design-system/Buttons/Button';
import Dialog from '@material-hu/components/design-system/Dialog';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { createGroup, getGroupDetails } from 'src/services/groupsService';
import {
  GroupPrivacyPolicies,
  GroupApprovalPolicies,
  GroupPublicationPolicies,
  CreateGroupBody,
} from 'src/types/groups';
import { removeURLParams, signedUpload } from 'src/utils/filesUtils';
import { formatTitle } from 'src/utils/helmetUtils';
import { formatDefaultIcon, formatOutgoingIcon } from 'src/utils/icons';
import { logEvent, LogEvents } from 'src/utils/logging';

import GroupManagementLayout from '../components/GroupManagementLayout';
import ManageConfiguration from '../components/ManageConfiguration';
import MembersList from '../components/MembersList';
import { ConfigurationTool } from '../constants';
import { groupsKeys } from '../queries';
import { groupRoutes } from '../routes';

const { CONFIGURATION, MANAGE_MEMBERS } = ConfigurationTool;

type Step = {
  id: ConfigurationTool;
  label: string;
  icon: TablerIcon;
  Component: React.ComponentType<{
    disabled?: boolean;
  }>;
  disabled?: boolean;
};

const NewGroup = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const groupId = searchParams.get('groupId');
  const [activeStep, setActiveStep] = useState<ConfigurationTool>(
    groupId ? MANAGE_MEMBERS : CONFIGURATION,
  );

  const { t } = useTranslation(['group']);
  const navigate = useNavigate();
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();
  const HuGoThemeProvider = useHuGoTheme();

  useEffect(() => {
    logEvent(LogEvents.GROUPS_GROUP_INICIATED);
  }, []);

  const steps: Step[] = [
    {
      id: CONFIGURATION,
      label: t('group:configuration'),
      icon: IconSettings,
      Component: ManageConfiguration,
      disabled: activeStep !== CONFIGURATION,
    },
    {
      id: MANAGE_MEMBERS,
      label: t('group:collaborators'),
      icon: IconList,
      Component: MembersList,
      disabled: activeStep !== MANAGE_MEMBERS,
    },
  ];

  const form = useForm({
    defaultValues: {
      title: '',
      description: '',
      banner: undefined,
      icon: formatDefaultIcon(),
      privacyPolicy: GroupPrivacyPolicies.OPEN,
      approvalPolicy: GroupApprovalPolicies.NOT_NEEDED,
      publicationPolicy: GroupPublicationPolicies.OPEN,
      isMultiCompany: false,
      membersCanLeave: 'false',
    },
    mode: 'onChange',
  });

  const { title, icon } = form.watch();

  const { mutate: createNewGroup, isLoading: isCreatingGroup } = useMutation(
    async ({ banner, ...body }: CreateGroupBody) => {
      let bannerUrl = banner?.url ? removeURLParams(banner?.url) : null;

      if (banner?.file) {
        const signedURL = await signedUpload(banner.file);
        bannerUrl = removeURLParams(signedURL);
      }
      return createGroup({
        ...body,
        bannerUrl,
      });
    },
    {
      onSuccess: ({ data }) => {
        logEvent(LogEvents.GROUPS_GROUP_CREATED, {
          groupId: data?.id,
          groupType: data?.privacyPolicy,
        });
        enqueueSnackbar({
          title: t('group:create_success'),
          variant: 'success',
        });
        form.reset({
          ...form.getValues(),
          ...data,
          membersCanLeave: data?.membersCanLeave ? 'true' : 'false',
        });
        setSearchParams({ groupId: data.id.toString() });
        showAssignMembersModal();
      },
      onError: err => showGeneralError(err),
    },
  );

  const { isLoading: isLoadingGroup } = useQuery(
    groupsKeys.groupDetails(groupId!),
    () => getGroupDetails(groupId!),
    {
      onSuccess: ({ data }) => {
        form.reset({ ...form.getValues(), title: data.title, icon: data.icon });
      },
      onError: err => {
        showGeneralError(err, t('group:error_loading_group'));
      },
      enabled: !!groupId && !title,
    },
  );

  const {
    modal: assignMembersModal,
    showModal: showAssignMembersModal,
    closeModal: closeAssignMembersModal,
  } = useModal(
    () => (
      <Dialog
        title={t('group:group_created')}
        textBody={t('group:select_collaborators')}
        primaryButtonProps={{
          children: t('group:assign_members'),
          onClick: () => {
            setActiveStep(MANAGE_MEMBERS);
            closeAssignMembersModal();
          },
        }}
        secondaryButtonProps={{
          children: t('general:later'),
          onClick: () => {
            closeAssignMembersModal();
            navigate(groupRoutes.base());
          },
        }}
        onClose={() => {
          closeAssignMembersModal();
          navigate(groupRoutes.base());
        }}
      />
    ),
    { maxWidth: 'xs' },
  );

  const activeConfiguration = steps.find(step => step.id === activeStep);

  const handleCreate = () => {
    const formValues = form.getValues();

    createNewGroup({
      ...formValues,
      description: formValues?.description || undefined,
      icon: formatOutgoingIcon(formValues?.icon),
      banner: formValues?.banner,
      membersCanLeave: formValues?.membersCanLeave === 'true',
      // isMultiCompany: formValues?.isMultiCompany,
    });
  };

  let footerActions: ReactNode = null;
  if (activeStep === CONFIGURATION) {
    footerActions = (
      <>
        <Button
          variant="tertiary"
          size="large"
          onClick={() => navigate(-1)}
        >
          {t('general:cancel')}
        </Button>
        <Button
          variant="primary"
          size="large"
          onClick={handleCreate}
          disabled={!title || !!groupId}
          loading={isCreatingGroup}
        >
          {t('group:group_creation')}
        </Button>
      </>
    );
  }

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(t('group:group_creation'))}</title>
      </Helmet>
      <FormProvider {...form}>
        <GroupManagementLayout
          title={title || t('group:create_group')}
          icon={icon}
          steps={steps}
          activeComponent={
            activeConfiguration ? <activeConfiguration.Component /> : null
          }
          footerActions={footerActions}
          onClose={() => navigate(groupRoutes.base())}
          activeStep={activeStep}
          onStepSelect={step => setActiveStep(step as ConfigurationTool)}
          isLoading={isLoadingGroup}
        />
      </FormProvider>
      {assignMembersModal}
    </HuGoThemeProvider>
  );
};

export default NewGroup;
