import React, { createElement } from "react";
import PropTypes from "prop-types";
import createStyles from "../styles/createStyles";

const { Children } = React;

const Arrow = ({ expanded, styles }) => (
	<span
		style={{
			...styles.base,
			...(expanded ? styles.expanded : styles.collapsed),
		}}
	>
		▶
	</span>
);

interface IProps {
	expanded: boolean;
	onClick: () => void;
	nodeRenderer: (args: any) => JSX.Element;
	title?: any;
	shouldShowArrow: boolean;
	shouldShowPlaceholder: boolean;
	onContextMenu?: () => void;
	name?: string;
	data?: any;
}

class TreeNode extends React.PureComponent<IProps> {
	constructor(props: IProps) {
		super(props);
	}

	static contextTypes = {
		theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
	};

	render() {
		const {
			expanded = true,
			onClick = () => {},
			onContextMenu,
			children,
			nodeRenderer = ({ name }) => <span>{name}</span>,
			title,
			shouldShowArrow = false,
			shouldShowPlaceholder = true,
		} = this.props;

		const { theme } = this.context;
		const styles = createStyles("TreeNode", theme);
		const renderedNode = createElement(nodeRenderer, this.props);
		const childNodes = expanded ? children : undefined;

		return (
			<li aria-expanded={expanded} role="treeitem" style={styles.treeNodeBase} title={title}>
				<div style={styles.treeNodePreviewContainer} onClick={onClick} onContextMenu={onContextMenu}>
					{shouldShowArrow || Children.count(children) > 0 ? (
						<Arrow expanded={expanded} styles={styles.treeNodeArrow} />
					) : (
						shouldShowPlaceholder && <span style={styles.treeNodePlaceholder}>&nbsp;</span>
					)}
					{renderedNode}
				</div>

				<ol role="group" style={styles.treeNodeChildNodesContainer}>
					{childNodes}
				</ol>
			</li>
		);
	}
}

export default TreeNode;
