import React, { useEffect, useRef, useState } from 'react';
import { Image, View } from 'react-native';
import type { ListRenderItem, StyleProp, ViewStyle } from 'react-native';
import { debounce, isEmpty } from 'lodash';
import { BottomSheetFlatList } from '@gorhom/bottom-sheet';
import FiltersSection from '../FiltersSection';
import ArtistRow from './ArtistRow';
import type { Artist } from './ArtistRow';
import SearchField from '../SearchField';
import ZeroState from '../ZeroState';
import CenteredActivityIndicator from '../CenteredActivityIndicator';
import Row from '../../componentsDS/Row';
import SearchBar from '../../componentsDS/SearchBar';
import { safeWithTheme } from '../../branding';
import type { ThemeProps } from '../../branding/hoc/types';
import { formatMessage } from '../../i18n';
import useArtistFilterSearch from '../../hooks/useArtistFilterSearch';
import useHasFeature from '../../hooks/auth/useHasFeature';
import { MOBILE_BOTTOM_SHEET_SEARCH } from '../../constants/features';
import { SEARCH_DEBOUNCE } from '../../constants';
import styles, { type Styles } from './styles';

export const getIsArtistSelected = (
    artist: Artist,
    artistsSelected: Artist[]
) => artistsSelected.some(selectedArtist => artist.id === selectedArtist.id);

interface FilterArtistProps {
    artistsSelected: Artist[];
    onArtistPress: (artist: Artist) => void;
    style?: StyleProp<ViewStyle>;
    hasRedesignBottomSheet?: boolean;
}

const keyExtractor = (artist: Artist) => artist.id;

export const FilterArtist = ({
    artistsSelected,
    onArtistPress,
    theme,
    style,
    hasRedesignBottomSheet
}: FilterArtistProps & ThemeProps) => {
    const { query, changeQuery, clearQuery, artists, loading } =
        useArtistFilterSearch();
    const hasBottomSheetSearch = useHasFeature(MOBILE_BOTTOM_SHEET_SEARCH);
    const hasSearchBar = Boolean(
        hasRedesignBottomSheet && hasBottomSheetSearch
    );
    const [searchInputValue, setSearchInputValue] = useState('');
    const [pinnedArtists, setPinnedArtists] = useState(artistsSelected);
    const themeStyles = styles[theme] as unknown as Styles;

    const changeQueryRef = useRef(changeQuery);
    changeQueryRef.current = changeQuery;
    const debouncedChangeQuery = useRef(
        debounce(
            (term: string) => changeQueryRef.current(term),
            SEARCH_DEBOUNCE
        )
    ).current;

    useEffect(
        () => () => debouncedChangeQuery.cancel(),
        [debouncedChangeQuery]
    );

    const handleSearchTextChange = (text: string) => {
        setSearchInputValue(text);
        const trimmedText = text.trim();
        if (trimmedText) {
            debouncedChangeQuery(trimmedText);
        } else {
            debouncedChangeQuery.cancel();
            clearQuery();
            setPinnedArtists(artistsSelected);
        }
    };

    const getArtists = () => {
        const selectedArtistNames = artistsSelected.map(a => a.name);
        const otherArtists = artists.filter(
            artist => !selectedArtistNames.includes(artist.name)
        );

        return (
            <>
                {artistsSelected.length && !query ? (
                    <View>
                        {artistsSelected.map(artist => (
                            <ArtistRow
                                onPress={onArtistPress}
                                artist={artist}
                                checked={getIsArtistSelected(
                                    artist,
                                    artistsSelected
                                )}
                                key={artist.id}
                            />
                        ))}
                    </View>
                ) : null}
                {otherArtists.map(artist => (
                    <ArtistRow
                        onPress={onArtistPress}
                        artist={artist}
                        checked={getIsArtistSelected(artist, artistsSelected)}
                        key={artist.id}
                    />
                ))}
            </>
        );
    };

    if (hasSearchBar) {
        const isSearching = !isEmpty(query);
        const listData = isSearching
            ? artists
            : [
                  ...pinnedArtists,
                  ...artists.filter(
                      artist => !getIsArtistSelected(artist, pinnedArtists)
                  )
              ];

        const renderItem: ListRenderItem<Artist> = ({ item }) => (
            <Row
                variant="multiSelect"
                label={item.name}
                selected={getIsArtistSelected(item, artistsSelected)}
                onPress={() => onArtistPress(item)}
                icon={
                    <Image
                        style={themeStyles.searchRowImage}
                        source={{ uri: item.imageUrl }}
                    />
                }
                testID={item.id}
            />
        );

        return (
            <View style={[themeStyles.container, style]}>
                <SearchBar
                    value={searchInputValue}
                    onChangeText={handleSearchTextChange}
                    placeholder={formatMessage(
                        'filtering.searchArtistsPlaceholder'
                    )}
                    clearAccessibilityLabel={formatMessage(
                        'filtering.searchClear'
                    )}
                    containerStyle={themeStyles.searchBar}
                />
                {loading ? (
                    <CenteredActivityIndicator />
                ) : isEmpty(listData) ? (
                    <ZeroState
                        style={themeStyles.zeroState}
                        title={formatMessage('addLabels.zeroState.title', {
                            term: query
                        })}
                        message={formatMessage('addLabels.zeroState.message')}
                    />
                ) : (
                    <BottomSheetFlatList
                        data={listData}
                        renderItem={renderItem}
                        keyExtractor={keyExtractor}
                        keyboardShouldPersistTaps="handled"
                        keyboardDismissMode="on-drag"
                        style={themeStyles.searchList}
                        contentContainerStyle={themeStyles.searchListContent}
                    />
                )}
            </View>
        );
    }

    return (
        <View style={[themeStyles.container, style]}>
            <FiltersSection dividerVisible={false}>
                <SearchField
                    style={themeStyles.searchBox}
                    inputContainerStyle={themeStyles.searchBoxInput}
                    onChangeQuery={changeQuery}
                    onClear={clearQuery}
                    onClearInput={clearQuery}
                    placeholder={`${formatMessage('filtering.title')}...`}
                />
                {loading ? (
                    <CenteredActivityIndicator />
                ) : isEmpty(artists) ? (
                    <ZeroState
                        style={themeStyles.zeroState}
                        title={formatMessage('addLabels.zeroState.title', {
                            term: query
                        })}
                        message={formatMessage('addLabels.zeroState.message')}
                    />
                ) : (
                    getArtists()
                )}
            </FiltersSection>
        </View>
    );
};

export default safeWithTheme(FilterArtist);
