import React, { useMemo, useState, useCallback } from 'react';
import { bem } from 'utils/bem';
import { pluralizeString } from 'utils/string';
import { Label, ArtistTeam, CurrentUserInfo, ArtistSearch } from 'backend-api/models';
import { PrimaryLabel } from 'common/components/typography';
import { Button } from 'common/components/button';
import { Icon } from 'common/components/icon';
import { Dropdown, Option } from 'common/components/custom-select';
import { Tooltip } from 'common/components/tooltip';
import { SMultipleTeamEntry, BEM_CLASS } from './s-multiple-team-entry';
import { isArtistTeamEditor } from 'common/transducers';
import { TeamOption } from './components';

interface MultipleTeamEntryProps {
  labels: Label[];
  user: CurrentUserInfo;
  teams?: ArtistTeam[];
  artist?: ArtistSearch;
  onEditTeam(team: ArtistTeam): void;
  onCreateTeam(label: Label): void;
  onViewTeam(team: ArtistTeam): void;
}

const classes = bem(BEM_CLASS);

export const MultipleTeamEntry = React.memo(
  ({ labels, user, teams, artist, onEditTeam, onCreateTeam, onViewTeam }: MultipleTeamEntryProps) => {
    const [isDropdownActive, setIsDropdownActive] = useState(false);

    const buttonArrowName = isDropdownActive ? 'up' : 'down';
    const allTeamsUsers = useMemo(() => teams?.flatMap(({ users }) => users) || [], [teams]);
    const isTeamEditor = isArtistTeamEditor(user, allTeamsUsers);

    const toggleDropdown = useCallback(
      (e: React.SyntheticEvent) => {
        e.stopPropagation();
        setIsDropdownActive(!isDropdownActive);
      },
      [isDropdownActive]
    );

    const hideDropdown = useCallback(() => {
      setIsDropdownActive(false);
    }, []);

    const handleCreateTeam = useCallback(
      (label: Label) => {
        onCreateTeam(label);
        hideDropdown();
      },
      [hideDropdown, onCreateTeam]
    );

    const handleEditTeam = useCallback(
      (team: ArtistTeam) => {
        onEditTeam(team);
        hideDropdown();
      },
      [hideDropdown, onEditTeam]
    );

    const handleViewTeam = useCallback(
      (team: ArtistTeam) => {
        onViewTeam(team);
        hideDropdown();
      },
      [hideDropdown, onViewTeam]
    );

    const button = useMemo(() => {
      if (!teams || teams.length === 0) {
        return user.isAdmin ? (
          <Tooltip content={`Create a team for ${artist?.name}`}>
            <Button variant="primary-cta" onClick={toggleDropdown} dataSelector="create-artist-multi-team-button">
              <Icon name="plus" />
              Create team
              <Icon name={buttonArrowName} />
            </Button>
          </Tooltip>
        ) : null;
      } else {
        return (
          <Button onClick={toggleDropdown} dataSelector={`${user.isAdmin ? 'manage' : 'view'}-teams-button`}>
            {user.isAdmin || isTeamEditor
              ? 'Manage teams'
              : `View ${teams.length} ${pluralizeString('team', teams.length)}`}
            <Icon name={buttonArrowName} />
          </Button>
        );
      }
    }, [buttonArrowName, isTeamEditor, teams, artist, toggleDropdown, user]);

    const options = useMemo(() => {
      if (!teams || teams.length === 0) {
        return user.isAdmin
          ? labels.map(label => (
              <Option
                key={label.id}
                dataSelector="artist-team-label"
                text={label.name}
                icon="add-bold"
                onClick={() => handleCreateTeam(label)}
              />
            ))
          : null;
      } else {
        const teamsLabels = teams.map(({ label }) => label.id);
        const createTeamLabels = labels.filter(({ id }) => !teamsLabels.includes(id));
        const teamsOptions = teams.map(team => {
          const isTeamEditor = isArtistTeamEditor(user, team.users);

          return user.isAdmin || isTeamEditor ? (
            <TeamOption team={team} isEditable onClick={handleEditTeam} />
          ) : (
            <Tooltip content="View team details">
              <div>
                <TeamOption team={team} onClick={handleViewTeam} />
              </div>
            </Tooltip>
          );
        });

        return (
          <>
            {teamsOptions}
            {user.isAdmin && createTeamLabels.length > 0 && (
              <>
                <div className={classes('divider')} />
                <PrimaryLabel className={classes('create-team-label')}>CREATE TEAM</PrimaryLabel>
                {createTeamLabels.map((label, index) => (
                  <Option
                    key={index}
                    dataSelector="artist-team-label"
                    text={label.name}
                    icon="add-bold"
                    onClick={() => handleCreateTeam(label)}
                  />
                ))}
              </>
            )}
          </>
        );
      }
    }, [teams, user, labels, handleCreateTeam, handleEditTeam, handleViewTeam]);

    return (
      <SMultipleTeamEntry>
        {button}
        <Dropdown
          className={classes('dropdown')}
          scrollerClassName={classes('scroller')}
          isVisible={isDropdownActive}
          hideDropdown={hideDropdown}
          dataSelector="artist-team-labels-dropdown"
        >
          {options}
        </Dropdown>
      </SMultipleTeamEntry>
    );
  }
);
