"use strict";

const React = require("react");
const classnames = require("classnames");
const axios = require("axios");
const syncpipe = require("syncpipe");
const matchValue = require("match-value");

const style = require("./datasheet-search.css");

function getSources(results) {
	return syncpipe(results, [
		(_) => _.map((result) => result.source),
		// (_) => _.filter((source) => source != null),
		(_) => _.map((source) => source != null ? source : "unknown"),
		(_) => new Set(_),
		(_) => Array.from(_),
		(_) => _.map((source) => {
			return matchValue(source, {
				tme: "TME",
				lcsc: "LCSC",
				st: "STMicroelectronics",
				farnell: "Farnell",
				unknown: "Unknown"
			});
		})
	]);
}

function SearchResult({ isFirst, name, description, url, manufacturer }) {
	// FIXME: Handle 'no datasheet available'
	return (
		<div className={classnames(style.result, { [style.first]: isFirst })}>
			<a href={url} className={style.download} target="_blank">
				Download datasheet
			</a>
			<div className={style.name}>
				<span className={style.manufacturer}>
					{manufacturer}
				</span>
				<span className={style.model}>
					{name}
				</span>
			</div>
			<div className={style.description}>
				{description}
			</div>
		</div>
	);
}

function NoResults() {
	return (
		<div className={style.noResults}>
			No results.
		</div>
	);
}

module.exports = function DatasheetSearch({}) {
	let [ query, setQuery ] = React.useState(""); // FIXME
	let [ results, setResults ] = React.useState([]);
	let [ sources, setSources ] = React.useState([]);
	let cancellationToken = React.useRef();

	function updateQuery(event) {
		setQuery(event.target.value.trim());
	}

	React.useEffect(() => {
		let cancelled = false;
		cancellationToken.current = axios.CancelToken.source();

		if (query.length > 0) {
			axios.post("/search", {}, {
				params: { query: query }
			})
				.then((response) => {
					if (!cancelled) {
						setResults(response.data.results);

						setSources(getSources(response.data.results));
					}
				})
				.catch((error) => {
					if (!axios.isCancel()) {
						throw error;
					}
				});
		} else {
			setResults([]);
		}

		return function () {
			cancelled = true;
			cancellationToken.current.cancel("Query input changed");
		};
	}, [ query ]);

	return (
		<div className="search">
			<input type="text" className={style.query} placeholder="Start typing a part number..." onChange={updateQuery} />
			<div className={style.sources}>
				{(results.length > 0)
					? <>
						<strong>Sources:</strong>
						&nbsp;
						{sources.join(", ")}
					</>
					: null
				}
			</div>
			<div className={style.results}>
				{(results.length > 0)
					? results.map((result, i) => {
						return <SearchResult
							isFirst={(i === 0)}
							{...result}
						/>;
					})
					: <NoResults />
				}
			</div>
		</div>
	);
};
