import { encodeRuleName } from 'Engine/rules.js'
import Fuse from 'fuse.js'
import { sortBy, pick } from 'ramda'
import React from 'react'
import Highlighter from 'react-highlight-words'
import { withNamespaces } from 'react-i18next'
import { Link, Redirect } from 'react-router-dom'
import Select from 'react-select'
import 'react-select/dist/react-select.css'
import { capitalise0 } from '../utils'

class SearchBar extends React.Component {
	componentDidMount() {
		this.inputElement.focus()
	}
	UNSAFE_componentWillMount() {
		let { rules } = this.props
		var options = {
			keys: [
				{
					name: 'name',
					weight: 0.3
				},
				{
					name: 'title',
					weight: 0.3
				},
				{
					name: 'espace',
					weight: 0.2
				},
				{
					name: 'description',
					weight: 0.2
				}
			]
		}
		this.fuse = new Fuse(
			rules.map(pick(['title', 'espace', 'description', 'name', 'dottedName'])),
			options
		)
	}
	state = {
		selectedOption: null,
		inputValue: null
	}
	handleChange = selectedOption => {
		this.setState({ selectedOption })
	}
	renderOption = ({ title, dottedName }) => (
		<span>
			<Highlighter
				searchWords={[this.state.inputValue]}
				textToHighlight={title}
			/>
			<span style={{ opacity: 0.6, fontSize: '75%', marginLeft: '.6em' }}>
				<Highlighter
					searchWords={[this.state.inputValue]}
					textToHighlight={dottedName}
				/>
			</span>
		</span>
	)
	filterOptions = (options, filter) => this.fuse.search(filter)
	render() {
		let { i18n, rules } = this.props,
			{ selectedOption } = this.state

		if (selectedOption != null) {
			this.props.finally && this.props.finally()
			return (
				<Redirect
					to={'../règle/' + encodeRuleName(selectedOption.dottedName)}
				/>
			)
		}
		return (
			<>
				<Select
					value={selectedOption && selectedOption.dottedName}
					onChange={this.handleChange}
					onInputChange={inputValue => this.setState({ inputValue })}
					valueKey="dottedName"
					labelKey="title"
					options={rules}
					filterOptions={this.filterOptions}
					optionRenderer={this.renderOption}
					placeholder={i18n.t('Entrez des mots clefs ici')}
					noResultsText={i18n.t('noresults', {
						defaultValue: "Nous n'avons rien trouvé…"
					})}
					ref={el => {
						this.inputElement = el
					}}
				/>
				{this.props.showDefaultList && !this.state.inputValue && (
					<ul>
						{sortBy(rule => rule.title, rules).map(rule => (
							<li key={rule.dottedName}>
								<Link
									to={
										this.props.rulePagesBasePath +
										'/' +
										encodeRuleName(rule.name)
									}>
									{rule.title || capitalise0(rule.name)}
								</Link>
							</li>
						))}
					</ul>
				)}
			</>
		)
	}
}

export default withNamespaces()(SearchBar)