import type { FC } from 'react';
import React, { useState, useEffect, memo } from 'react';
import { Button, SkeletonLoader } from '@theorchard/suite-components';
import cx from 'classnames';
import { map } from 'lodash-es';
import { STORE } from '../../../constants';
import { formatMessage } from '../../../locale';
import ArtistProfileComponent from '../../artistPopover/artistProfile';
import ArtistProfileCheckable from '../artistProfileCheckable';
import NoResultIcon from '../svg/no-result';
import type { ArtistStoreProfile } from '../../../types';
import type { PageContext } from '../types';

const CLASS_NAME = 'ArtistProfilesList';

interface Props {
    id: string;
    store: number;
    titleContent?: string | JSX.Element | (string | JSX.Element)[];
    emptyProfileContent?: string | JSX.Element | (string | JSX.Element)[];
    profiles: ArtistStoreProfile[];
    isVisible: boolean;
    onChange?: (args: { id: string; profile: ArtistStoreProfile | null }) => void;
    onValidate?: (context: PageContext) => void;
    isAnalyticsMode?: boolean;
    onFetchMore?: (store: number) => Promise<unknown>;
    hasMoreResult?: boolean;
}

export const ArtistProfilesList: FC<Props> = ({
    id,
    store,
    titleContent,
    emptyProfileContent,
    profiles,
    isVisible = true,
    onChange,
    onValidate,
    isAnalyticsMode,
    onFetchMore,
    hasMoreResult = true,
}) => {
    const [selectedProfile, selectProfile] = useState<ArtistStoreProfile | null>(null);
    const [isFetchingMore, setIsFetchingMore] = useState(false);
    useEffect(() => {
        if (onValidate && isVisible)
            onValidate({ id, store, selectedProfile, data: [], tabId: '1' });
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [selectedProfile, isVisible]);

    const handleChange = (profile: ArtistStoreProfile | null) => {
        selectProfile(profile);
        if (onChange) onChange({ id, profile });
    };

    const handleOnFetchMore = () => {
        if (onFetchMore) {
            setIsFetchingMore(true);
            void onFetchMore(store).then(() => setIsFetchingMore(false));
        }
    };

    const renderNoResult = () => (
        <div className={`${CLASS_NAME}-no-result`}>
            <NoResultIcon />
            <p className={`${CLASS_NAME}-no-result-text`}>
                {formatMessage(
                    store === STORE.SPOTIFY
                        ? 'artistProfileList.noResultSpotify'
                        : 'artistProfileList.noResultApple'
                )}
            </p>
        </div>
    );
    const renderProfile = (profile: ArtistStoreProfile | null) => {
        if (!profile && !emptyProfileContent) return null;

        const key = profile?.name ?? 'empty';

        return (
            <ArtistProfileCheckable
                key={key}
                id={`${id}-${key}`}
                name={id}
                onChange={() => handleChange(profile)}
                checked={selectedProfile === profile}
                overClick
            >
                {profile ? (
                    <ArtistProfileComponent
                        profile={profile}
                        store={store}
                        isAnalyticsMode={isAnalyticsMode}
                    />
                ) : (
                    emptyProfileContent
                )}
            </ArtistProfileCheckable>
        );
    };
    const renderFetchingMore = () => {
        if (isFetchingMore) return <SkeletonLoader />;

        if (hasMoreResult)
            return (
                <Button
                    className={`${CLASS_NAME}-content-link`}
                    variant="link"
                    onClick={() => handleOnFetchMore()}
                >
                    {formatMessage('artistProfileList.showMoreResults')}
                </Button>
            );

        return (
            <div className={`${CLASS_NAME}-no-result`}>
                <p className={`${CLASS_NAME}-no-more-result-text`}>
                    {formatMessage('artistProfileList.noMoreResults')}
                </p>
            </div>
        );
    };

    return (
        <div className={cx(CLASS_NAME, { [`${CLASS_NAME}-hidden`]: !isVisible })}>
            {titleContent && <div className={`${CLASS_NAME}-title`}>{titleContent}</div>}
            <div className={`${CLASS_NAME}-items`}>
                {renderProfile(null)}
                {map(profiles, (profile) => renderProfile(profile))}
                {!profiles?.length && renderNoResult()}
            </div>
            {Boolean(profiles?.length) && (
                <div className={`${CLASS_NAME}-fetch-more`}>{renderFetchingMore()}</div>
            )}
        </div>
    );
};

export default memo(ArtistProfilesList);
