import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Footer } from 'app/components/footer';
import { ResponsiveContainer } from 'common/components/sidebar-form/responsive-container';
import { ProjectHeader } from 'common/containers/project-header';
import { WaveBackground } from 'common/components/wave-background';
import { useProjectApproverAccessRestricted, useProjectCurrencyCode, useQuery } from 'hooks';
import { ProjectTab } from 'common-v2/types';
import { ProjectDetails } from '../components/project-details';
import {
  closeShareWindow,
  getBudgetGroupsForProjectAction,
  getNotesHistoryAction,
  getProject,
  getProjectHistoryAction,
  getProjectMarketingMixAction,
  getProjectTeamUsersInfo,
  getTeamCountersAction,
  resetProject,
  shareProject,
  toggleShareWindow,
} from '../actions';
import {
  activeProjectSelector,
  errorSelector,
  isShareWindowOpenedSelector,
  projectUsersSelector,
  shareProgressSelector,
  teamSelector,
} from '../selectors';
import { AnalyticsEvents, trackEvent } from 'utils/analytic';
import { ShareModalContainer } from 'modals/sharing-modal';
import { ShareModalContext, ShareModalResponse } from 'modals/sharing-modal/types';
import { ViewTeamModalMode } from 'common/types';
import { closeTeamModal, getProjectArtistTeam, openTeamModal } from 'common/actions';
import { ViewTeamModalContainer } from './view-team-modal-container';
import { navigateTo } from 'utils/navigation';
import { Optional } from 'backend-api/models';
import { paths } from 'app/routing/paths';
import { PermissionErrorModalContainer } from 'modals/permission-error-modal';
import { useProjectAccessRestricted } from 'common/hooks/use-project-access-restricted';
import { BulkCampaignsAssignmentModalContainer } from 'modals/bulk-campaigns-assignment';
import { prepareSearchUsers } from 'project/transducers';
import { useAppContext } from 'common-v2/hooks';
import { OutdatedGlobalLayout } from 'app/components/outdated-global-layout';
import { getFromSearchParams } from 'common/transducers';
import { getProjectName } from 'common-v2/transducers';
import { Head } from 'app/components/head';

interface MatchParams {
  id: string;
}

export const ProjectDetailsContainer = (props: RouteComponentProps<MatchParams>) => {
  const { match, history } = props;

  const projectId = parseInt(match.params.id, 10);

  const dispatch = useDispatch();
  const { labels } = useAppContext();

  const [isAssignCampaignsLoading, setIsAssignCampaignsLoading] = useState(false);
  const project = useSelector(activeProjectSelector);
  const isShareLoading = useSelector(shareProgressSelector);
  const isShareOpened = useSelector(isShareWindowOpenedSelector);
  const team = useSelector(teamSelector);
  const projectUsers = useSelector(projectUsersSelector);
  const error = useSelector(errorSelector);
  const params = useQuery();

  useProjectAccessRestricted(errorSelector);
  useProjectApproverAccessRestricted();

  useEffect(() => trackEvent(AnalyticsEvents.SUMMARY_TAB_VIEWED), []);

  useEffect(() => {
    if (labels) {
      dispatch(
        getProject.request({
          projectId,
          ...getFromSearchParams(params.query),
        })
      );

      dispatch(getBudgetGroupsForProjectAction.request(projectId));
    }
    return () => {
      dispatch(resetProject());
      dispatch(closeShareWindow());
    };
  }, [dispatch, labels, params.query, projectId]);

  useEffect(() => {
    if (project) {
      dispatch(getProjectHistoryAction.request({ id: project.id, isUnassigned: project.isClaimed }));
      dispatch(getTeamCountersAction.request(project.id));
      dispatch(getProjectMarketingMixAction.request(project.id));
      dispatch(getNotesHistoryAction.request(project.id));
      dispatch(getProjectArtistTeam.request(project.id));
    }
  }, [dispatch, project]);

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

  useEffect(() => {
    if (isShareOpened) {
      dispatch(getProjectTeamUsersInfo.request(projectId));
    }
  }, [isShareOpened, dispatch, projectId]);

  const onClose = useCallback(() => dispatch(closeShareWindow()), [dispatch]);
  const onShare = useCallback(
    (shareInfo: ShareModalResponse) =>
      dispatch(shareProject.request({ projectId, shareInfo, closeShareProjectModal: onClose })),
    [dispatch, onClose, projectId]
  );

  const [viewTeamModalMode, setViewTeamModalMode] = useState(ViewTeamModalMode.ARTIST_TEAM);

  const openArtistTeamModal = useCallback(() => {
    setViewTeamModalMode(ViewTeamModalMode.ARTIST_TEAM);
    dispatch(openTeamModal());
  }, [dispatch]);

  const openViewProjectCollaboratorsModal = useCallback(() => {
    setViewTeamModalMode(ViewTeamModalMode.PROJECT_COLLABORATORS);
    dispatch(getProjectTeamUsersInfo.request(projectId));
    dispatch(openTeamModal());
  }, [dispatch, projectId]);

  const openEditProjectCollaboratorsModal = useCallback(() => {
    dispatch(toggleShareWindow());
  }, [dispatch]);

  const onCloseTeamModal = useCallback(() => dispatch(closeTeamModal()), [dispatch]);

  const navigateToArtistPage = useCallback(
    (artistId: Optional<string>) => {
      artistId && navigateTo(paths.artist(artistId));
      onCloseTeamModal();
    },
    [onCloseTeamModal]
  );

  const onCampaignsAssign = useCallback(() => {
    setIsAssignCampaignsLoading(true);
  }, []);

  const onCampaignsAssigned = useCallback(() => {
    setIsAssignCampaignsLoading(false);

    if (project) {
      dispatch(getProject.request({ projectId }));
      dispatch(getProjectHistoryAction.request({ id: project.id, isUnassigned: project.isClaimed }));
      dispatch(getTeamCountersAction.request(project.id));
      dispatch(getProjectMarketingMixAction.request(project.id));
      dispatch(getNotesHistoryAction.request(project.id));
      dispatch(getProjectArtistTeam.request(project.id));
    }
  }, [project, dispatch, projectId]);

  const projectCurrencyCode = useProjectCurrencyCode();

  const shareModalSearchUsers = useMemo(() => prepareSearchUsers(projectUsers), [projectUsers]);

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

  return (
    <>
      <Head title={getProjectName(project)} />
      <OutdatedGlobalLayout>
        <ProjectHeader key={Number(project?.isClaimed)} projectId={projectId} activeTab={ProjectTab.Summary} />
        <WaveBackground className="app__wrapper">
          <ResponsiveContainer>
            <ProjectDetails
              projectId={projectId}
              currencyCode={projectCurrencyCode}
              openArtistTeamModal={openArtistTeamModal}
              openViewProjectCollaboratorsModal={openViewProjectCollaboratorsModal}
              openEditProjectCollaboratorsModal={openEditProjectCollaboratorsModal}
              openArtistPage={navigateToArtistPage}
              isAssignCampaignsLoading={isAssignCampaignsLoading}
            />
          </ResponsiveContainer>
          <Footer />
        </WaveBackground>
        <ShareModalContainer
          context={ShareModalContext.PROJECT_COLLABORATORS}
          title="Share Project"
          isLoading={isShareLoading}
          isOpened={isShareOpened}
          onClose={onClose}
          onShare={onShare}
          teamUsers={team}
          searchUsers={shareModalSearchUsers}
          isConfidential={project?.isConfidential}
        />
        <ViewTeamModalContainer
          mode={viewTeamModalMode}
          closeTeamModal={onCloseTeamModal}
          openArtistPage={navigateToArtistPage}
        />
        {project && (
          <BulkCampaignsAssignmentModalContainer
            project={project}
            onCampaignsAssign={onCampaignsAssign}
            onCampaignsAssigned={onCampaignsAssigned}
          />
        )}
        <PermissionErrorModalContainer />
      </OutdatedGlobalLayout>
    </>
  );
};
