import React, { useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { SmallArtistsSection } from 'projects/components/small-artists-section';
import { noop } from 'lodash';
import { bem } from 'utils/bem';
import { LoadableData, LoadingState } from 'common/types';
import {
  expansionLiveArtistTeamsSelector,
  expansionLiveProjectsSelector,
  expansionUpcomingArtistTeamsSelector,
  expansionUpcomingProjectsSelector,
} from 'projects/selectors';
import { GetExpansionProjectsPayload } from 'projects/types';
import {
  getExpansionLiveProjects,
  getExpansionUpcomingProjects,
  getLiveArtistTeams,
  getUpcomingArtistTeams,
} from 'projects/actions';
import { ArtistRosterItem, ArtistRosterModel } from 'backend-api/models';
import FailedToLoadSvg from 'assets/failed-to-load-gray.svg';
import { NoResults } from 'common/components/no-results';
import { BEM_CLASS, SArtistRoster } from './s-artist-roster';
import { LiveArtist } from '../live-artist';
import { navigateTo } from 'utils/navigation';
import { paths } from 'app/routing/paths';
import { AnalyticsEvents, trackEvent } from 'utils/analytic';

const classes = bem(BEM_CLASS);

interface Props {
  artistRosterData: LoadableData<ArtistRosterModel>;
  expandedLiveArtistId?: string;
  expandedUpcomingArtistId?: string;
  onLiveArtistExpand(id?: string): void;
  onUpcomingArtistExpand(id?: string): void;
}

export const ArtistRoster = React.memo(
  ({
    artistRosterData,
    onLiveArtistExpand,
    onUpcomingArtistExpand,
    expandedLiveArtistId,
    expandedUpcomingArtistId,
  }: Props) => {
    const dispatch = useDispatch();
    const [isUpcomingExpanded, setUpcomingExpanded] = useState(true);
    const [isInactiveExpanded, setInactiveExpanded] = useState(false);

    const loadingState = artistRosterData.loading;
    const { live, planned, inactive } = artistRosterData.data;

    const onUpcomingExpand = useCallback(() => setUpcomingExpanded(!isUpcomingExpanded), [isUpcomingExpanded]);
    const onInactiveExpand = useCallback(() => setInactiveExpanded(!isInactiveExpanded), [isInactiveExpanded]);

    const liveArtistTeamsLoadable = useSelector(expansionLiveArtistTeamsSelector);
    const liveProjectsLoadable = useSelector(expansionLiveProjectsSelector);
    const upcomingArtistTeamsLoadable = useSelector(expansionUpcomingArtistTeamsSelector);
    const upcomingProjectsLoadable = useSelector(expansionUpcomingProjectsSelector);

    const handleGetLiveArtistTeams = useCallback(
      (id: string) => {
        dispatch(getLiveArtistTeams.request(id));
      },
      [dispatch]
    );

    const handleGetExpansionLiveProjects = useCallback(
      (payload: GetExpansionProjectsPayload) => {
        dispatch(getExpansionLiveProjects.request(payload));
      },
      [dispatch]
    );

    const handleGetUpcomingArtistTeams = useCallback(
      (id: string) => {
        dispatch(getUpcomingArtistTeams.request(id));
      },
      [dispatch]
    );

    const handleGetExpansionUpcomingProjects = useCallback(
      (payload: GetExpansionProjectsPayload) => {
        dispatch(getExpansionUpcomingProjects.request(payload));
      },
      [dispatch]
    );

    const shouldShowSection = useCallback(
      (items: ArtistRosterItem[]) => {
        switch (loadingState) {
          case LoadingState.Idle:
          case LoadingState.Started:
            return true;
          case LoadingState.Finished:
            return items.length > 0;
          case LoadingState.Failed:
            return false;
        }
      },
      [loadingState]
    );

    const onInactiveItemClicked = useCallback((id: string) => {
      navigateTo(paths.artist(id));
      trackEvent(AnalyticsEvents.NON_ACTIVE_ARTIST_SELECTED, { artist_selected: id });
    }, []);

    const onUpcomingItemClicked = useCallback(
      (id: string) => {
        onUpcomingArtistExpand(id);
        trackEvent(AnalyticsEvents.NON_ACTIVE_ARTIST_SELECTED, { artist_selected: id });
      },
      [onUpcomingArtistExpand]
    );

    const onLiveItemClicked = useCallback(
      (id: string) => {
        onLiveArtistExpand(id);
        trackEvent(AnalyticsEvents.LIVE_ARTIST_CARD_EXPANDED, { artist_selected: id });
      },
      [onLiveArtistExpand]
    );

    return (
      <SArtistRoster>
        {loadingState === LoadingState.Failed && (
          <NoResults
            className={classes('error')}
            withoutFiltersMessage="Data failed to load. Try refreshing this page."
            withoutFiltersImage={FailedToLoadSvg}
          />
        )}
        {shouldShowSection(live) && (
          <LiveArtist
            items={live}
            expandedArtistId={expandedLiveArtistId}
            onItemExpand={onLiveItemClicked}
            loadingState={loadingState}
            artistTeamLoadable={liveArtistTeamsLoadable}
            projectsLoadable={liveProjectsLoadable}
            getArtistTeams={handleGetLiveArtistTeams}
            getExpansionProjects={handleGetExpansionLiveProjects}
          />
        )}
        {shouldShowSection(planned) && (
          <SmallArtistsSection
            className={classes('upcoming-section')}
            title="Upcoming Artists"
            items={planned}
            isExpanded={isUpcomingExpanded}
            onExpand={onUpcomingExpand}
            canExpandItem={true}
            expandedArtistId={expandedUpcomingArtistId}
            onItemExpand={onUpcomingItemClicked}
            isLoading={loadingState === LoadingState.Started}
            artistTeamLoadable={upcomingArtistTeamsLoadable}
            projectsLoadable={upcomingProjectsLoadable}
            getArtistTeams={handleGetUpcomingArtistTeams}
            getExpansionProjects={handleGetExpansionUpcomingProjects}
          />
        )}
        {shouldShowSection(inactive) && (
          <SmallArtistsSection
            className={classes('inactive-section')}
            title="Inactive Artists"
            items={inactive}
            isExpanded={isInactiveExpanded}
            onExpand={onInactiveExpand}
            isLoading={loadingState === LoadingState.Started}
            getArtistTeams={noop}
            getExpansionProjects={noop}
            onItemExpand={onInactiveItemClicked}
            paginationEnabled
          />
        )}
      </SArtistRoster>
    );
  }
);
