import React from 'react';
import PropTypes from 'prop-types';
import IconUtil from '../../util/IconUtil';
import trunc from '../../util/Trunc';
import IDUtil from '../../util/IDUtil';
import RegexUtil from '../../util/RegexUtil';

export default class SearchSnippet extends React.Component {

	constructor(props) {
		super(props);
		this.CLASS_PREFIX = "ss";
	}

	static createMarkup(text) {
		return { __html: text };
	}

	//NOTE: when needed this function can be extended with an anonymous user check in combination with:
	//collectionConfig.getAnonymousUserRestrictions().prohibitThumbnails === true
	renderPosterImage = posterURL => {
		if (!posterURL) return null;

		return (
			<div className={IDUtil.cssClassName("poster", this.CLASS_PREFIX)}>
				<img
					className="media-object"
					src="/static/images/placeholder.2b77091b.svg"
					data-src={posterURL}
					alt="Could not find image"
				/>
			</div>
		);
	};

	renderMediaIcons = mediaTypes => {
		if (!mediaTypes) return null;

		return mediaTypes.map(mt => {
			let title = null;
			switch(mt) {
				case 'video' : title = "Video content"; break;
				case 'audio' : title = "Audio content"; break;
				case 'image' : title = "Image content"; break;
				case 'text' : title = "Textual content"; break;
			}
			return (
				<span key={'__mi__' + mt} className={IconUtil.getMimeTypeIcon(mt, false, true, false)} title={title}/>
			);
		});
	};

	renderAccessabilityIcon = isPlayable => {
		//Note: assigning a media type (to the result data) automatically means it's accessible in the media suite!
		if (isPlayable) {
			// Data  should be visible by default, so prevent any clutter
			// by showing for all items they are visible.
			return null;
		} else {
			return (
				<span className={IconUtil.getMediaObjectAccessIcon(false, false, true, true, false)} title="Media object(s) not accessible"/>
			);
		}
	};

	renderTags = tags => {
		if (!tags) return null;

		return tags.map(t => {
			return <span>{t}</span>;
		});
	};

	renderFragmentIcon = () => {
		return (
			<span
				className={IconUtil.getMimeTypeIcon("fragment", true, true)}
				title="Media fragment"
			/>
		);
	};

	renderFragmentSnippet = fragment => {
		if (!fragment) return null;
		return (
			<div className={IDUtil.cssClassName("fragment", this.CLASS_PREFIX)}>
				{fragment.snippet}
			</div>
		);
	};

	renderHighlights = (collectionConfig, snippets, highlightRegex) => {
		if(!snippets) return null;

		//TODO use collectionConfig.getNumberOfHighlightsToDisplay to cull the amount of snippets shown
		const markup = Object.keys(snippets).map(field => {
			return "</br><span class=fieldNameText>" +
				collectionConfig.toPrettyFieldName(field) +
				"</span>: &nbsp;" +
				snippets[field].map(hl => RegexUtil.highlightText(hl, highlightRegex))
		});
		return <div
			className={IDUtil.cssClassName("snippet-description", this.CLASS_PREFIX)}
			dangerouslySetInnerHTML={SearchSnippet.createMarkup(markup)}
		/>
	};

	fixMsg = s => (s ? s.replace(new RegExp(/\|$/,"g"), "") : null);

	//possible default fields: posterURL, title, description, tags
	render() {
		const poster = this.renderPosterImage(this.props.data.posterURL);
		const mediaTypes = this.renderMediaIcons(this.props.data.mediaTypes);
		const accessIcon = this.renderAccessabilityIcon(
			this.props.data.playable
		);
		const tags = this.renderTags(this.props.data.tags);

		let fragmentIcon,
			fragmentSnippet = null;
		if (this.props.data.type === "media_fragment") {
			fragmentIcon = this.renderFragmentIcon();
			fragmentSnippet = this.renderFragmentSnippet(
				this.props.data.mediaFragment
			);
		}

		const classNames = [IDUtil.cssClassName("search-snippet")];
		const title = this.props.data.title ? this.props.data.title + " " : "";
		const date = this.props.data.date ? this.props.data.date : "";
		const subHeading = (
			<div>
				<i>{date}</i>
				<span>{this.fixMsg(this.props.data.highlightMsg)}</span>
			</div>
		);

		const highlights = this.renderHighlights(
			this.props.collectionConfig,
			this.props.data.matchesPerField,
			this.props.data.highlightRegex
		);

		return (
			<div className={classNames.join(" ")} onClick={this.props.onClick}>
				{poster}

				<div className={IDUtil.cssClassName('media-body', this.CLASS_PREFIX)}>
					{/* Title */}
					<h3 className={IDUtil.cssClassName('title',	this.CLASS_PREFIX)} title={this.props.data.id}>
						<span dangerouslySetInnerHTML={
							SearchSnippet.createMarkup(RegexUtil.highlightText(
								title ? trunc(title, 200) : "",
								this.props.searchRegex
							))
						}/>
						{/* Icons access */}
						<span className={IDUtil.cssClassName("icon-access", this.CLASS_PREFIX)}>{accessIcon}</span>
					</h3>

					{/* Description snippet with possible highlights */}
					<div
						className={IDUtil.cssClassName("snippet-description", this.CLASS_PREFIX)}
						dangerouslySetInnerHTML={SearchSnippet.createMarkup(
							RegexUtil.highlightText(
								RegexUtil.findFirstHighlightInText(
									this.props.data.description,
									this.props.searchRegex,
									35
								),
								this.props.searchRegex
							)
						)}
					/>
                    {highlights}
					{fragmentSnippet}

					{/* Info heading/icons */}
					<div className={IDUtil.cssClassName("info",	this.CLASS_PREFIX)}>
						{/* Icons type */}
						<div className={IDUtil.cssClassName('icon-type', this.CLASS_PREFIX)}>
							{mediaTypes}{fragmentIcon}
						</div>
						{subHeading}
					</div>

					{tags}
				</div>
			</div>
		);
	}
}

SearchSnippet.propTypes = {
	onClick: PropTypes.func.isRequired, // click callback
	collectionConfig: PropTypes.object.isRequired,
	searchRegex: PropTypes.instanceOf(RegExp), //the search regex that was used to find this hit (if there is a search term)
	data: PropTypes.shape({
		//all the data required to draw the information of this result snippet (see SearchResult.toSearchResultSnippet())
		id: PropTypes.string.isRequired,
		title: PropTypes.string.isRequired,
		description: PropTypes.string,
		date: PropTypes.string,
		posterURL: PropTypes.string, //for loading a poster image
		playable: PropTypes.bool, //for drawing the accessability icon
		mediaTypes: PropTypes.arrayOf(PropTypes.string), //for drawing media type icons
		tags: PropTypes.array, //for drawing any type of annotations (e.g. based on a the current user)
		highlightRegex : PropTypes.regexp,
		matchesPerField: PropTypes.object, //key = field name, value = array with highlights {text : '', regex : ''}
		highlightMsg: PropTypes.string,

		//this is only available when the search is configured to return media fragments (inner_hits)
		mediaFragment: PropTypes.shape({
			assetId: PropTypes.string,
			url: PropTypes.string,
			start: PropTypes.number,
			end: PropTypes.number,
			snippet: PropTypes.string,
			layer: PropTypes.string
		})
	}).isRequired
};
