"use strict";

const React = require("react");
const asExpression = require("as-expression");

const defaultStyle = require("./style.css");
const useTheme = require("../../util/themeable");
const ListItemContext = require("../../contexts/list-item");
const comparePath = require("../../util/compare-path");
const useClickTimer = require("../../util/use-click-timer");

function Expander({ expanded, onClick }) {
	let { withTheme } = useTheme({ control: "list", defaultStyle });

	return (
		<div className={withTheme("expander")} onClick={onClick}>
			{(expanded === true)
				? "▼"
				: "▶"}
		</div>
	);	
}

function ExpanderPlaceholder() {
	let { withTheme } = useTheme({ control: "list", defaultStyle });

	return <div className={withTheme("expanderPlaceholder")} />;
}

module.exports = function ListItem({ label, id, children }) {
	let { onClick, onDoubleClick, path, selectedPath } = React.useContext(ListItemContext);
	let [ expanded, setExpanded ] = React.useState(true);
	let { withTheme } = useTheme({ control: "list", defaultStyle });
	let doubleClickTimer = useClickTimer(500);

	let depth = path.length;
	let indent = depth * 11; // FIXME: Figure out a way to do this with CSS instead, eg. via value exports?
	let ownPath = path.concat([ id ]);
	let isSelected = comparePath(selectedPath, ownPath);

	function handleClick() {
		if (doubleClickTimer.click()) {
			if (onDoubleClick != null) {
				onDoubleClick(ownPath);
			} else if (children != null) {
				// TODO: Check whether we really only want to do this when no onDoubleClick handler is specified, ie. only as a default behaviour
				toggleExpanded();
			}
		}
	}

	function handleMouseDown() {
		if (doubleClickTimer.mouseDown()) {
			onClick(ownPath);
		}
	}

	function toggleExpanded() {
		setExpanded((expanded) => !expanded);
	}

	let style = {
		paddingLeft: `${indent}px`
	};

	return (
		<React.Fragment>
			{/* FIXME: item_selected capitalization */}
			<div className={withTheme("uilibComponent", "item", { item_selected: isSelected })} style={style} onMouseDown={handleMouseDown} onClick={handleClick}>
				{(children != null)
					? <Expander expanded={expanded} onClick={toggleExpanded} />
					: <ExpanderPlaceholder />}
				<div className={withTheme("label")}>
					{label}
				</div>
			</div>
			{(children != null && expanded === true)
				? asExpression(() => {
					let itemContext = {
						path: ownPath,
						selectedPath: selectedPath,
						onClick: onClick,
						onDoubleClick: onDoubleClick
					};
				
					return (
						<ListItemContext.Provider value={itemContext}>
							{children}
						</ListItemContext.Provider>
					);
				})
				: null}
		</React.Fragment>
	);
};
