import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';

import {FormattedMessage} from 'react-intl';
import {Virtuoso} from 'react-virtuoso';
import {useSelector} from 'react-redux';

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

import {BadgeID, AllBadgesBadge} from '../../types/badges';
import Client from '../../client/api';

import {RHSState} from '../../types/general';
import {IMAGE_TYPE_EMOJI, RHS_STATE_DETAIL, RHS_STATE_TYPES} from '../../constants';
import {isCreateBadgeModalVisible, getEditBadgeModalData} from '../../selectors';

import AllBadgesRow from './all_badges_row';

import './all_badges.scss';

type Props = {
    filterTypeId?: number | null;
    filterTypeName?: string | null;
    actions: {
        setRHSView: (view: RHSState) => void;
        setRHSBadge: (badge: BadgeID | null) => void;
        getCustomEmojisByName: (names: string[]) => void;
        openCreateBadgeModal: () => void;
    };
}

const AllBadges: React.FC<Props> = ({filterTypeId, filterTypeName, actions}) => {
    const [loading, setLoading] = useState(true);
    const [badges, setBadges] = useState<AllBadgesBadge[]>([]);
    const isFiltered = filterTypeId != null;

    const createBadgeVisible = useSelector(isCreateBadgeModalVisible);
    const editBadgeData = useSelector(getEditBadgeModalData);
    const isModalOpen = createBadgeVisible || editBadgeData !== null;
    const wasModalOpen = useRef(false);

    const fetchBadges = useCallback(() => {
        const client = new Client();
        client.getAllBadges().then((data) => {
            setBadges(data);
            setLoading(false);

            const names: string[] = [];
            data.forEach((badge) => {
                if (badge.image_type === IMAGE_TYPE_EMOJI) {
                    names.push(badge.image);
                }
            });
            const toLoad = names.filter((v) => !systemEmojis.has(v));
            actions.getCustomEmojisByName(toLoad);
        });
    }, []); // eslint-disable-line react-hooks/exhaustive-deps

    useEffect(() => {
        fetchBadges();
    }, [fetchBadges]);

    useEffect(() => {
        if (wasModalOpen.current && !isModalOpen) {
            fetchBadges();
        }
        wasModalOpen.current = isModalOpen;
    }, [isModalOpen, fetchBadges]);

    const displayBadges = useMemo(() => {
        if (!isFiltered) {
            return badges;
        }
        return badges.filter((b) => b.type === filterTypeId);
    }, [badges, isFiltered, filterTypeId]);

    const onBadgeClick = useCallback((badge: AllBadgesBadge) => {
        actions.setRHSBadge(badge.id);
        actions.setRHSView(RHS_STATE_DETAIL);
    }, [actions]);

    if (loading) {
        return (
            <div className='AllBadges__loadingWrap'>
                <div className='spinner'/>
            </div>
        );
    }

    const isEmpty = !isFiltered && (!badges || badges.length === 0);

    return (
        <>
            {isFiltered && (
                <div className='AllBadges__header'>
                    <div className='AllBadges__backHeader'>
                        <button
                            className='AllBadges__backButton'
                            onClick={() => actions.setRHSView(RHS_STATE_TYPES)}
                        >
                            {'← '}
                            <FormattedMessage
                                id='badges.rhs.back_to_types'
                                defaultMessage='Назад к типам'
                            />
                        </button>
                        <span className='AllBadges__filterTitle'>{filterTypeName}</span>
                    </div>
                </div>
            )}
            {isEmpty && (
                <div className='AllBadges__emptyContent'>
                    <div className='AllBadges__emptyTitle'>
                        <FormattedMessage
                            id='badges.empty.title'
                            defaultMessage='Достижений пока нет'
                        />
                    </div>
                    <div className='AllBadges__emptyDescription'>
                        <FormattedMessage
                            id='badges.empty.description'
                            defaultMessage='Создайте первое достижение, чтобы отмечать заслуги участников команды.'
                        />
                    </div>
                </div>
            )}
            {!isEmpty && displayBadges.length === 0 && (
                <div className='AllBadges__empty'>
                    <FormattedMessage
                        id='badges.types.no_badges'
                        defaultMessage='В этом типе нет достижений'
                    />
                </div>
            )}
            {!isEmpty && displayBadges.length > 0 && (
                <Virtuoso
                    style={{flex: '1 1 auto'}}
                    data={displayBadges}
                    increaseViewportBy={300}
                    overscan={200}
                    itemContent={(_index, badge) => (
                        <AllBadgesRow
                            key={badge.id}
                            badge={badge}
                            onClick={onBadgeClick}
                        />
                    )}
                />
            )}
        </>
    );
};

export default AllBadges;
