import React, { useCallback, useEffect, useMemo } from 'react';
import { ArtistRosterProject, ArtistSearch, ArtistTeam, Campaign } from 'backend-api/models';
import { ExpandingSection } from 'projects/components/expanding-section';
import { getPhaseMock } from 'backend-api/models/phase/__mocks__';
import { useDispatch, useSelector } from 'react-redux';
import { LoadableData } from 'common/types';
import { getArtistRoster, getProjectsSnapshots, resetExpansions } from 'projects/actions';
import { getParamsForProjectsSnapshots, getProjectsMaxSnapshotPeriods } from './transducers';
import { currentLabelSelector } from 'projects/selectors';
import { GetExpansionProjectsPayload, ProjectSnapshotParams } from 'projects/types';
import { UPCOMING_STATUS } from 'common/constants';
import { isDateAfter, isDateBefore } from 'common-v2/utils';

interface Props {
  isExpanded?: boolean;
  artist: ArtistSearch;
  artistTeamLoadable: LoadableData<ArtistTeam[]>;
  projectsLoadable: LoadableData<ArtistRosterProject[]>;
  arrowPosition?: number;
  onCollapseFinish?(): void;
  className?: string;
  getExpansionProjects(payload: GetExpansionProjectsPayload): void;
  getArtistTeams(id: string): void;
}

export const ArtistRosterExpansionContainer = React.memo(
  ({
    artist,
    className,
    isExpanded,
    onCollapseFinish,
    artistTeamLoadable,
    projectsLoadable,
    getExpansionProjects,
    getArtistTeams,
    arrowPosition,
  }: Props) => {
    const dispatch = useDispatch();

    const currentLabel = useSelector(currentLabelSelector);

    useEffect(() => {
      if (!artist) return;
      getArtistTeams(artist.id);

      if (currentLabel) {
        getExpansionProjects({
          id: artist.id,
          params: {
            labelId: currentLabel,
          },
        });
      }
    }, [artist, currentLabel, dispatch, getArtistTeams, getExpansionProjects]);

    const currentPhase = getPhaseMock();

    const loadProjectsMetrics = useCallback(
      (params: ProjectSnapshotParams[]) => {
        dispatch(getProjectsSnapshots.request(params));
      },
      [dispatch]
    );

    useEffect(() => {
      if (!isExpanded || projectsLoadable.data.length === 0) {
        return;
      }
      const periods = getProjectsMaxSnapshotPeriods(projectsLoadable.data, new Date());
      const params = getParamsForProjectsSnapshots(periods);

      if (params.length == 0) {
        return;
      }

      loadProjectsMetrics(params);
    }, [loadProjectsMetrics, projectsLoadable.data, isExpanded, dispatch]);

    useEffect(() => {
      return () => {
        dispatch(resetExpansions());
      };
    }, [dispatch]);

    const onCampaignsAssigned = useCallback(
      (project: ArtistRosterProject, assignedCampaigns: Campaign[]) => {
        if (!artist) return;
        if (currentLabel) {
          getExpansionProjects({
            id: artist.id,
            params: {
              labelId: currentLabel,
            },
          });

          const isCampaignsInCurrentDateRange = assignedCampaigns.some(
            campaign =>
              (campaign.endDate &&
                isDateBefore(campaign.startDate, new Date()) &&
                isDateAfter(campaign.endDate, new Date())) ||
              true
          );

          if (isCampaignsInCurrentDateRange && project.status === UPCOMING_STATUS.id) {
            dispatch(getArtistRoster.request(currentLabel));
          }
        }
      },
      [artist, currentLabel, dispatch, getExpansionProjects]
    );

    const artistTeam = useMemo(() => artistTeamLoadable.data.find(team => team.label.id === currentLabel), [
      artistTeamLoadable,
      currentLabel,
    ]);

    return (
      <ExpandingSection
        onCollapseFinish={onCollapseFinish}
        arrowPosition={arrowPosition}
        artist={artist}
        className={className}
        isExpanded={isExpanded}
        artistTeam={artistTeam}
        projects={projectsLoadable}
        currentPhase={currentPhase}
        onCampaignsAssigned={onCampaignsAssigned}
      />
    );
  }
);
