import React, { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Form } from '../components/form';
import { getLabelUsers } from 'common/actions';
import { activeProjectSelector, errorSelector, processingSelector } from '../selectors';
import { getFieldsWithDiffValues, getInitialValues } from '../transducers';
import { usePermissionsChecker, useProjectApproverAccessRestricted } from 'hooks';
import {
  claimUnassignedProject,
  editProject,
  getProject,
  getUnassignedProjectCampaigns,
  ProjectInput,
  resetProject,
} from '../actions';
import { RouteComponentProps } from 'react-router-dom';
import { PermissionErrorModalContainer } from 'modals/permission-error-modal';
import { useProjectAccessRestricted } from 'common/hooks/use-project-access-restricted';
import { paths } from 'app/routing/paths';
import { ACCESS_PERMISSIONS } from 'common-v2/constants';
import { useAppContext } from 'common-v2/hooks';
import { OutdatedGlobalLayout } from 'app/components/outdated-global-layout';
import { Head } from 'app/components/head';
import { getProjectName } from 'common-v2/transducers';

interface MatchParams {
  id: string;
}

export const ProjectFormContainer = (props: RouteComponentProps<MatchParams>) => {
  const { history } = props;
  const paramsId = props.match.params.id;

  const id = parseInt(paramsId);

  const dispatch = useDispatch();
  const { user: userInfo, labels } = useAppContext();

  const project = useSelector(activeProjectSelector);
  const error = useSelector(errorSelector);
  const isProcessing = useSelector(processingSelector);
  const initialValues = getInitialValues(id, project, userInfo, labels);
  const isClaimed = !!project && project.isClaimed;

  const permissionsChecker = usePermissionsChecker(project);
  const canEditProject = permissionsChecker(ACCESS_PERMISSIONS.EDIT_PROJECT);

  useProjectAccessRestricted(errorSelector);
  useProjectApproverAccessRestricted();

  useEffect(() => {
    if (project && !canEditProject) {
      history.replace(paths.projectDetails(project.id));
    }
  }, [canEditProject, history, project, project?.id]);

  useEffect(() => {
    if (isNaN(id) || error?.statusCode === 404) {
      history.replace(paths.outdatedNotFound());
    }
  }, [error, history, id]);

  useEffect(() => {
    if (project && project.label) {
      dispatch(getLabelUsers.request(project.label.id));
    } else if (labels?.[0]) {
      dispatch(getLabelUsers.request(labels[0].id));
    }
  }, [dispatch, labels, project]);

  useEffect(() => {
    if (!!project && !project?.isClaimed) dispatch(getUnassignedProjectCampaigns.request(project.id));
  }, [dispatch, project]);

  useEffect(() => {
    dispatch(getProject.request({ projectId: id }));

    return () => {
      dispatch(resetProject());
      dispatch(getLabelUsers.success([]));
    };
  }, [dispatch, id]);

  const handleSubmit = useCallback(
    (data: ProjectInput) => {
      if (isProcessing) return;

      if (!isClaimed) {
        dispatch(
          claimUnassignedProject.request({
            data,
            projectId: id,
          })
        );

        return;
      }

      dispatch(
        editProject.request({
          data,
          projectId: id,
          changedFields: getFieldsWithDiffValues(data, initialValues),
        })
      );
    },
    [dispatch, initialValues, id, isProcessing, isClaimed]
  );

  return (
    <>
      <Head title={getProjectName(project)} />
      <OutdatedGlobalLayout>
        <Form handleSubmit={handleSubmit} initialValues={initialValues} projectId={id} />
        <PermissionErrorModalContainer />
      </OutdatedGlobalLayout>
    </>
  );
};
