import {UserProfile} from 'mattermost-redux/types/users';
import React, {useCallback, useEffect, useMemo, useState} from 'react';

import {FormattedMessage, useIntl} from 'react-intl';

import {useDispatch, useSelector} from 'react-redux';

import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common';

import {getCustomEmojisByName} from 'mattermost-redux/actions/emojis';

import {EmojiIndicesByAlias} from 'utils/emoji';

import {UserBadge} from 'types/badges';
import Client from 'client/api';
import BadgeImage from '../badge_image/badge_image';
import {IMAGE_TYPE_EMOJI, RHS_STATE_DETAIL, RHS_STATE_MY, RHS_STATE_OTHER} from '../../constants';
import {setRHSView, setRHSBadge, setRHSUser, openGrant} from '../../actions/actions';
import {getShowRHS} from 'selectors';
import {groupBadges} from 'components/utils/badge_list_utils';

import BadgeTooltip from './badge_tooltip';
import TooltipWrapper from './tooltip_wrapper';
import './badge_list.scss';

type Props = {
    user: UserProfile;
    hide: () => void;
}

const MAX_BADGES = 6;
const BADGE_SIZE = 24;

const BadgeList: React.FC<Props> = ({user, hide}) => {
    const intl = useIntl();
    const dispatch = useDispatch();
    const currentUserID = useSelector(getCurrentUserId);
    const openRHS = useSelector(getShowRHS);
    const [badges, setBadges] = useState<UserBadge[]>();
    const [loaded, setLoaded] = useState(false);

    useEffect(() => {
        const c = new Client();
        c.getUserBadges(user.id).then((result) => {
            setBadges(result);
            setLoaded(true);
        });
    }, [user.id]);

    const groups = useMemo(
        () => (badges ? groupBadges(badges) : []),
        [badges],
    );

    useEffect(() => {
        if (!badges) {
            return;
        }
        const toShow = groups.slice(0, MAX_BADGES);
        const names = toShow.
            filter(({badge}) => badge.image_type === IMAGE_TYPE_EMOJI).
            map(({badge}) => badge.image).
            filter((v) => !EmojiIndicesByAlias.has(v));
        if (names.length > 0) {
            dispatch(getCustomEmojisByName(names));
        }
    }, [badges, groups, dispatch]);

    const handleMoreClick = useCallback(() => {
        if (!openRHS) {
            return;
        }
        if (currentUserID === user.id) {
            dispatch(setRHSView(RHS_STATE_MY));
        } else {
            dispatch(setRHSUser(user.id));
            dispatch(setRHSView(RHS_STATE_OTHER));
        }
        openRHS();
        hide();
    }, [openRHS, currentUserID, user.id, dispatch, hide]);

    const handleBadgeClick = useCallback((badge: UserBadge) => {
        if (!openRHS) {
            return;
        }
        dispatch(setRHSBadge(badge.id));
        dispatch(setRHSView(RHS_STATE_DETAIL));
        openRHS();
        hide();
    }, [openRHS, dispatch, hide]);

    const handleGrantClick = useCallback(() => {
        dispatch(openGrant(user.username));
        hide();
    }, [dispatch, user.username, hide]);

    if ((user as UserProfile & {remote_id?: string}).remote_id) {
        return null;
    }

    const visibleGroups = groups.slice(0, MAX_BADGES);
    const maxWidth = (MAX_BADGES * BADGE_SIZE) + 30;

    return (
        <div id='badgePlugin'>
            <div><b>
                <FormattedMessage
                    id='badges.popover.title'
                    defaultMessage='Достижения'
                />
            </b></div>
            <div id='contentContainer'>
                {visibleGroups.map(({badge, count}) => (
                    <TooltipWrapper
                        key={badge.id}
                        tooltipContent={
                            <BadgeTooltip
                                badge={badge}
                                count={count}
                            />
                        }
                    >
                        <a onClick={() => handleBadgeClick(badge)}>
                            <span className='badge-stacked'>
                                <BadgeImage
                                    badge={badge}
                                    size={BADGE_SIZE}
                                />
                                {count > 1 && (
                                    <span className='badge-stack-count'>
                                        {'×'}{count}
                                    </span>
                                )}
                            </span>
                        </a>
                    </TooltipWrapper>
                ))}
                {groups.length > MAX_BADGES && (
                    <TooltipWrapper
                        tooltipContent={intl.formatMessage(
                            {id: 'badges.and_more', defaultMessage: 'и ещё {count}. Нажмите, чтобы увидеть все.'},
                            {count: groups.length - MAX_BADGES},
                        )}
                    >
                        <button
                            id='showMoreButton'
                            onClick={handleMoreClick}
                        >
                            <span className={'fa fa-angle-right'}/>
                        </button>
                    </TooltipWrapper>
                )}
            </div>
            {!loaded && (
                <div style={{height: BADGE_SIZE, minWidth: 66, maxWidth}}>
                    <div className='spinner'/>
                </div>
            )}
            <button
                id='grantBadgeButton'
                onClick={handleGrantClick}
            >
                <span className={'fa fa-plus-circle'}/>
                <FormattedMessage
                    id='badges.grant_badge'
                    defaultMessage='Выдать достижение'
                />
            </button>
            <hr className='divider divider--expanded'/>
        </div>
    );
};

export default BadgeList;
