import React, { useCallback, useMemo, useState } from 'react';
import { BEM_CLASS, SExpandingSection } from 'projects/components/expanding-section/s-expanding-section';
import { bem } from 'utils/bem';
import { AnimatePresence, motion } from 'framer-motion';
import { BulkCampaignsAssignmentModalContainer } from 'modals/bulk-campaigns-assignment';
import { ResponsiveContainer } from 'common/components/sidebar-form/responsive-container';
import { ArtistRosterProject, ArtistSearch, ArtistTeam, Campaign, Optional, Phase } from 'backend-api/models';
import { ExpansionHeader, Loader, ProjectCard } from 'projects/components/expanding-section/components';
import { LoadableData, LoadingState } from 'common/types';
import { Body } from 'common/components/typography';
import { sortProjectsByStatus } from './transducers';

interface Props {
  isExpanded?: boolean;
  artist: ArtistSearch;
  arrowPosition?: number;
  onCollapseFinish?(): void;
  projects: LoadableData<ArtistRosterProject[]>;
  artistTeam?: ArtistTeam;
  currentPhase: Phase;
  onCampaignsAssigned(project: ArtistRosterProject, assignedCampaigns: Campaign[]): void;
  className?: string;
}

export const classes = bem(BEM_CLASS);

const expandAnimationProps = {
  initial: { height: 0 },
  exit: { height: 0 },
  animate: { height: 'unset' },
  transition: { type: 'tween', duration: 0.2 },
};

export const ExpandingSection = React.memo(
  ({
    className,
    isExpanded,
    onCollapseFinish,
    artist,
    arrowPosition,
    projects,
    artistTeam,
    onCampaignsAssigned,
  }: Props) => {
    const [currentProject, setCurrentProject] = useState<Optional<ArtistRosterProject>>();
    const sortedProjects = useMemo(() => sortProjectsByStatus(projects.data), [projects.data]);

    const handleCampaignsAssigned = useCallback(
      (assignedCampaigns: Campaign[]) => {
        if (currentProject) {
          onCampaignsAssigned(currentProject, assignedCampaigns);
          setCurrentProject(undefined);
        }
      },
      [currentProject, onCampaignsAssigned]
    );

    const expansionElement = useMemo(() => {
      if (projects.loading === LoadingState.Finished) {
        return (
          <div className={classes('expansion')}>
            {artist && <ExpansionHeader artist={artist} artistTeam={artistTeam} />}
            <div className={classes('projects-list')}>
              {sortedProjects.map(project => (
                <ProjectCard key={project.id} project={project} />
              ))}
            </div>
          </div>
        );
      }

      if (projects.loading === LoadingState.Failed) {
        return <Body className={classes('error-container')}>Data failed to load. Try refreshing this page.</Body>;
      }

      return <Loader className={classes('loader-container')} />;
    }, [artist, artistTeam, projects.loading, sortedProjects]);

    return (
      <SExpandingSection layout="position" layoutId="expansion" className={className}>
        <AnimatePresence onExitComplete={onCollapseFinish}>
          {isExpanded && (
            <motion.div {...expandAnimationProps} className={classes('expanded-container')}>
              <div className={classes('expansion-background')} />
              <ResponsiveContainer>
                <div className={classes('inner')}>
                  <motion.div
                    className={classes('triangle')}
                    initial={{ left: arrowPosition }}
                    animate={{ left: arrowPosition }}
                    transition={{ type: 'tween', duration: 0.2 }}
                  />
                  {expansionElement}
                </div>
              </ResponsiveContainer>
            </motion.div>
          )}
        </AnimatePresence>
        {currentProject && (
          <BulkCampaignsAssignmentModalContainer
            project={currentProject}
            onCampaignsAssigned={handleCampaignsAssigned}
          />
        )}
      </SExpandingSection>
    );
  }
);
