import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { ArtistTeam, Label } from 'backend-api/models';
import { ProjectFilterParams } from 'backend-api/types';
import { LoadingState, ViewTeamModalMode } from 'common/types';
import { isTeamModalOpenedSelector } from 'common/selectors';
import { closeTeamModal, openTeamModal } from 'common/actions';
import { ViewTeamModal } from 'common/components/view-team-modal';
import { MultipleTeamEntry, SharingModalTitle, SingleTeamEntry } from 'artist/components';
import { artistSelector, selectedArtistTeamSelector, sharingModalSelector } from 'artist/selectors';
import {
  editArtistTeam,
  getArtistInfo,
  getLabelUsers,
  hideSharingModal,
  selectArtistTeam,
  showSharingModal,
} from 'artist/actions';
import { mapModalResponseToUpdateArtistTeamUsers } from 'artist/transducers';
import { ShareModalContainer } from 'modals/sharing-modal';
import { Mode, ShareModalContext, ShareModalResponse } from 'modals/sharing-modal/types';
import { useProjectsRequest } from 'artist/hooks';
import { ROLES } from 'common-v2/constants';
import { addTeamUsers } from 'modals/sharing-modal/actions';
import { useAppContext } from 'common-v2/hooks';

interface ArtistTeamsContainerProps {
  artistId: string;
  filterParams: ProjectFilterParams;
}

export const ArtistTeamsContainer = React.memo(({ artistId, filterParams }: ArtistTeamsContainerProps) => {
  const [selectedLabel, setSelectedLabel] = useState<Label>();

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

  const { data: artistInfo } = useSelector(artistSelector);
  const isTeamModalOpened = useSelector(isTeamModalOpenedSelector);
  const selectedArtistTeam = useSelector(selectedArtistTeamSelector);
  const sharingModal = useSelector(sharingModalSelector);

  const getProjects = useProjectsRequest(artistId, filterParams);

  const activeArtistTeam = artistInfo?.teams?.find(team => team.label.id === selectedLabel?.id);

  const teamUsers = useMemo(() => {
    if (activeArtistTeam) return activeArtistTeam.users;
    if (selectedLabel && userInfo) {
      dispatch(
        addTeamUsers({
          ...userInfo,
          roles: [
            {
              ...ROLES.EDITOR,
              categoryIds: [1, 2],
            },
          ],
          labels: [selectedLabel],
        })
      );
    }
    return [];
  }, [activeArtistTeam, userInfo, selectedLabel, dispatch]);

  const handleCreateTeam = useCallback(
    (label: Label) => {
      setSelectedLabel(label);
      dispatch(showSharingModal());
    },
    [dispatch]
  );

  const handleEditTeam = useCallback(
    (artistTeam: ArtistTeam) => {
      handleCreateTeam(artistTeam.label);
    },
    [handleCreateTeam]
  );

  const handleViewTeam = useCallback(
    (team: ArtistTeam) => {
      dispatch(selectArtistTeam(team));
      dispatch(openTeamModal());
    },
    [dispatch]
  );

  const handleEditSuccess = useCallback(() => {
    dispatch(
      getArtistInfo.request({
        id: artistId,
      })
    );

    getProjects();
  }, [artistId, dispatch, getProjects]);

  const handleShare = useCallback(
    (modalResponse: ShareModalResponse) => {
      if (!selectedLabel) return;
      if (!activeArtistTeam) {
        dispatch(
          editArtistTeam.request({
            artistId,
            onEditSuccess: handleEditSuccess,
            ...mapModalResponseToUpdateArtistTeamUsers(modalResponse, selectedLabel.id),
          })
        );
        return;
      }

      dispatch(
        editArtistTeam.request({
          artistId,
          onEditSuccess: handleEditSuccess,
          ...mapModalResponseToUpdateArtistTeamUsers(modalResponse, selectedLabel.id),
        })
      );
    },
    [activeArtistTeam, artistId, dispatch, selectedLabel, handleEditSuccess]
  );

  const handleSharingModalClose = useCallback(() => dispatch(hideSharingModal()), [dispatch]);

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

  const teamEntry = useMemo(() => {
    if (!userLabels || userLabels.length === 0 || !userInfo) return null;

    if (userLabels.length === 1) {
      return (
        <SingleTeamEntry
          label={userLabels[0]}
          team={artistInfo?.teams[0]}
          user={userInfo}
          onCreateTeam={handleCreateTeam}
          onEditTeam={handleEditTeam}
          onViewTeam={handleViewTeam}
        />
      );
    }

    return (
      <MultipleTeamEntry
        artist={artistInfo?.info}
        labels={userLabels}
        teams={artistInfo?.teams}
        user={userInfo}
        onCreateTeam={handleCreateTeam}
        onEditTeam={handleEditTeam}
        onViewTeam={handleViewTeam}
      />
    );
  }, [artistInfo?.info, artistInfo?.teams, handleCreateTeam, handleEditTeam, handleViewTeam, userInfo, userLabels]);

  useEffect(() => {
    if (sharingModal.data.isOpened && selectedLabel) {
      dispatch(getLabelUsers.request(selectedLabel.id));
    } else {
      setSelectedLabel(undefined);
    }
  }, [dispatch, sharingModal.data.isOpened, selectedLabel]);

  return (
    <>
      {teamEntry}
      <ShareModalContainer
        context={ShareModalContext.ARTIST_TEAM}
        title={<SharingModalTitle artist={artistInfo?.info.name} label={selectedLabel?.name} />}
        mode={activeArtistTeam ? Mode.EDIT : Mode.CREATION}
        onClose={handleSharingModalClose}
        onShare={handleShare}
        teamUsers={teamUsers}
        searchUsers={sharingModal.data.labelUsers.map(user => ({ ...user, labels: [] }))}
        isOpened={sharingModal.data.isOpened}
        isLoading={sharingModal.loading === LoadingState.Started}
      />
      <ViewTeamModal
        isOpened={isTeamModalOpened}
        users={selectedArtistTeam?.users || []}
        mode={ViewTeamModalMode.ARTIST_TEAM}
        artist={artistInfo?.info}
        label={selectedArtistTeam?.label}
        onClose={handleViewTeamModalClose}
      />
    </>
  );
});
