import React, { useState, useEffect } from 'react';
import { api, ShareWith, ShareType, ShareWithOption } from '../Common/Api';
import './ShareSelection.scss';

type Props = {
	selectShare: (selection: ShareWithOption) => void;
	shareType?: ShareType[];
	excluded?: {
		groupIds?: string[];
		userIds?: string[];
		circleIds?: string[];
	};
	placeholder?: string;
}

const ShareSelection: React.FC<Props> = (props) => {
	const [search, setSearch] = useState<string>('');
	const [hasFocus, setFocus] = useState<boolean>(false);
	const [showSearchResults, setShowSearchResults] = useState<boolean>(false);
	const [recommendations, setRecommendations] = useState<ShareWith>();
	const [searchResults, setSearchResults] = useState<ShareWith>();

	const shareType = props.shareType || [ShareType.User, ShareType.Group];
	const excluded = {
		userIds: props.excluded?.userIds || [],
		groupIds: props.excluded?.groupIds || [],
		circleIds: props.excluded?.circleIds || [],
	};
	const placeholder = props.placeholder || t('bbb', 'Name, group …');

	useEffect(() => {
		setSearchResults(undefined);
		const searchQuery = search;

		if (!searchQuery) {
			return;
		}

		api.searchShareWith(searchQuery, shareType).then(result => {
			if (searchQuery === search) {
				setSearchResults(result);
			}
		});
	}, [search]);

	useEffect(() => {
		api.getRecommendedShareWith(shareType).then(result => setRecommendations(result));
	}, []);

	useEffect(() => {
		setShowSearchResults(hasFocus);
	}, [hasFocus]);

	function preventOnBlurEvent(ev: React.MouseEvent) {
		ev.preventDefault();
	}

	async function selectShare(share: ShareWithOption) {
		props.selectShare(share);

		setSearch('');
	}

	function renderSearchResults(options: ShareWith|undefined) {
		const results = options ? [
			...options.exact.users.filter(user => !excluded.userIds.includes(user.value.shareWith)),
			...options.exact.groups.filter(group => !excluded.groupIds.includes(group.value.shareWith)),
			...options.exact.circles.filter(circle => !excluded.circleIds.includes(circle.value.shareWith)),
			...options.users.filter(user => !excluded.userIds.includes(user.value.shareWith)),
			...options.groups.filter(group => !excluded.groupIds.includes(group.value.shareWith)),
			...options.circles.filter(circle => !excluded.circleIds.includes(circle.value.shareWith)),
		] : [];

		const renderOption = (option: ShareWithOption) => {
			return (
				<li
					key={option.value.shareWith}
					className="suggestion"
					onMouseDown={preventOnBlurEvent}
					onClick={() => selectShare(option)}>
					{option.label}{option.value.shareType === ShareType.Group ? ` (${t('bbb', 'Group')})` : ''}
				</li>);
		};

		return (
			<ul className="bbb-selection">
				{!options ?
					<li><span className="icon icon-loading-small icon-visible"></span> {t('bbb', 'Searching')}</li> :
					(
						(results.length === 0 && search) ? <li>{t('bbb', 'No matches')}</li> : results.map(renderOption)
					)}
			</ul>
		);
	}

	return (
		<div className="bbb-selection-container">
			<input
				type="text"
				value={search}
				onChange={ev => setSearch(ev.currentTarget.value)}
				onFocus={() => setFocus(true)}
				onBlur={() => setFocus(false)}
				placeholder={placeholder} />
			{showSearchResults && renderSearchResults((search && searchResults) ? searchResults : ((recommendations && !search) ? recommendations : undefined))}
		</div>
	);
};

export default ShareSelection;