import type { FC } from 'react';
import React, { useCallback, useEffect } from 'react';
import { Card, LoadingIndicator } from '@theorchard/suite-components';
import {
    BRAND_AWAL,
    formatMessage,
    useIdentity,
} from '@theorchard/suite-frontend';
import { GlyphIcon } from '@theorchard/suite-icons';
import { debounce } from 'lodash';
import { useHistory } from 'react-router-dom';
import ReadError from 'src/components/errors/read-error';
import HeaderLabelPicker from 'src/components/headerLabelPicker';
import {
    useLazyLabelParticipantSearch,
    useLazyOwsSearch,
} from 'src/data/queries';
import { newSongFormUrl } from 'src/utils/urls';
import CatalogSongTable from './catalogSongTable';

export const SEARCH_DEBOUNCE_INTERVAL = 500;
export const SEARCH_RESULT_LIMIT = 20;

const SelectExistingSong: FC = () => {
    const history = useHistory();
    const { defaultBrand } = useIdentity();
    const [term, setTerm] = React.useState('');

    const [
        doParticipantSearch,
        {
            participants: labelParticipants,
            called: participantCalled,
            loading: labelParticipantSearchLoading,
            error: labelParticipantSearchError,
        },
    ] = useLazyLabelParticipantSearch();

    const [
        doOwsSearch,
        {
            songs: owsSearchTracks,
            products: owsSearchProducts,
            called: owsSearchCalled,
            loading: owsSearchLoading,
            error: owsSearchError,
        },
    ] = useLazyOwsSearch();

    // eslint-disable-next-line react-hooks/exhaustive-deps
    const debounceSearch = useCallback(
        debounce((searchTerm: string) => {
            const variables = { term: searchTerm, limit: SEARCH_RESULT_LIMIT };
            doParticipantSearch(variables);
            doOwsSearch({
                productReleaseStatus: 'in_content',
                ...variables,
            });
        }, SEARCH_DEBOUNCE_INTERVAL),
        []
    );

    useEffect(() => {
        debounceSearch(term.trim());
        return () => debounceSearch.cancel();
    }, [term, debounceSearch]);

    if (owsSearchError || labelParticipantSearchError)
        return (
            <ReadError error={owsSearchError || labelParticipantSearchError} />
        );

    const renderSearchResults = () => {
        if (owsSearchLoading || labelParticipantSearchLoading)
            return <LoadingIndicator />;

        const isOwsSearchResultIsEmpty =
            owsSearchTracks.length === 0 && owsSearchProducts.length === 0;

        const isQueriesCalled = participantCalled && owsSearchCalled;

        if (labelParticipants.length === 0 && isOwsSearchResultIsEmpty)
            return isQueriesCalled ? (
                formatMessage('selectExistingSong.noResults')
            ) : (
                <></>
            );

        return (
            <CatalogSongTable
                labelParticipants={labelParticipants}
                owsSearchTracks={owsSearchTracks}
                owsSearchProducts={owsSearchProducts}
            />
        );
    };

    return (
        <div className="SelectExistingSong">
            <div className="AppHeader">
                <HeaderLabelPicker />
            </div>

            <div className="PageContent">
                <div className="SelectExistingSong-title">
                    {formatMessage('selectExistingSong.registerNewSong')}
                </div>
                <Card suite>
                    <div className="SelectExistingSong-section-title">
                        {formatMessage('selectExistingSong.searchYourCatalog')}
                    </div>
                    <input
                        type="text"
                        className="SelectExistingSong-search-input form-control"
                        placeholder={formatMessage(
                            'selectExistingSong.searchPlaceholder'
                        )}
                        value={term}
                        onChange={e => setTerm(e.target.value)}
                    />
                    {renderSearchResults()}
                </Card>

                <Card suite>
                    <div
                        className="SelectExistingSong-no-existing"
                        onClick={() => history.push(newSongFormUrl())}
                    >
                        {formatMessage(
                            'selectExistingSong.registerNonOrchardSong',
                            {
                                brand:
                                    defaultBrand === BRAND_AWAL
                                        ? 'AWAL'
                                        : 'The Orchard',
                            }
                        )}
                        <GlyphIcon name="arrowRight" size={12} />
                    </div>
                </Card>
            </div>
        </div>
    );
};

export default SelectExistingSong;
