import { h } from 'preact';
import { useState, useEffect, useRef } from 'preact/hooks';
import { log } from '../utils';
import { trackEvent } from '../analytics';
import { ItemTile } from './ItemTile';
import { Trans, t } from '@lingui/macro';
import { I18n } from '@lingui/react';

export default function SavedItemPane({
	itemsMap,
	isOpen,
	closeHandler,
	onItemSelect,
	onItemRemove,
	onItemFork,
	onExport,
	mergeImportedItems
}) {
	const [items, setItems] = useState([]);
	const [filteredItems, setFilteredItems] = useState([]);
	const searchInputRef = useRef();

	useEffect(() => {
		if (!itemsMap) return;
		const newItems = Object.values(itemsMap);
		newItems.sort(function (a, b) {
			return b.updatedOn - a.updatedOn;
		});
		setItems(newItems);
		setFilteredItems(newItems);
	}, [itemsMap]);

	useEffect(() => {
		// Opening
		if (isOpen) {
			searchInputRef.current.value = '';
			searchInputRef.current.focus();
		}
		// Closing
		if (!isOpen) {
			setFilteredItems([]);
		}
	}, [isOpen]);

	function onCloseIntent() {
		closeHandler();
	}
	function itemClickHandler(item) {
		onItemSelect(item);
	}
	function itemRemoveBtnClickHandler(item, e) {
		e.stopPropagation();
		onItemRemove(item);
	}
	function itemForkBtnClickHandler(item, e) {
		e.stopPropagation();
		onItemFork(item);
	}
	function keyDownHandler(event) {
		if (!isOpen) {
			return;
		}

		const isCtrlOrMetaPressed = event.ctrlKey || event.metaKey;
		const isForkKeyPressed = isCtrlOrMetaPressed && event.keyCode === 70;
		const isDownKeyPressed = event.keyCode === 40;
		const isUpKeyPressed = event.keyCode === 38;
		const isEnterKeyPressed = event.keyCode === 13;

		const selectedItemElement = $('.js-saved-item-tile.selected');
		const havePaneItems = $all('.js-saved-item-tile').length !== 0;

		if ((isDownKeyPressed || isUpKeyPressed) && havePaneItems) {
			const method = isDownKeyPressed ? 'nextUntil' : 'previousUntil';

			if (selectedItemElement) {
				selectedItemElement.classList.remove('selected');
				selectedItemElement[method](
					'.js-saved-item-tile:not(.hide)'
				).classList.add('selected');
			} else {
				$('.js-saved-item-tile:not(.hide)').classList.add('selected');
			}
			$('.js-saved-item-tile.selected').scrollIntoView(false);
		}

		if (isEnterKeyPressed && selectedItemElement) {
			const item = itemsMap[selectedItemElement.dataset.itemId];
			onItemSelect(item);
			trackEvent('ui', 'openItemKeyboardShortcut');
		}

		// Fork shortcut inside saved creations panel with Ctrl/⌘ + F
		if (isForkKeyPressed) {
			event.preventDefault();
			const item = itemsMap[selectedItemElement.dataset.itemId];
			itemForkBtnClickHandler(item);
			trackEvent('ui', 'forkKeyboardShortcut');
		}
	}

	function importFileChangeHandler(e) {
		var file = e.target.files[0];

		var reader = new FileReader();
		reader.addEventListener('load', progressEvent => {
			var items;
			try {
				items = JSON.parse(progressEvent.target.result);
				log(items);
				mergeImportedItems(items);
			} catch (exception) {
				log(exception);
				alert(
					i18n._(
						t`'Oops! Selected file is corrupted. Please select a file that was generated by clicking the "Export" button.`
					)
				);
			}
		});

		reader.readAsText(file, 'utf-8');
	}

	function importBtnClickHandler(e) {
		var input = document.createElement('input');
		input.type = 'file';
		input.style.display = 'none';
		input.accept = 'accept="application/json';
		document.body.appendChild(input);
		input.addEventListener('change', importFileChangeHandler);
		input.click();
		trackEvent('ui', 'importBtnClicked');
		e.preventDefault();
	}

	function searchInputHandler(e) {
		const text = e.target.value.toLowerCase().trim();
		if (!text) {
			setFilteredItems(items);
		} else {
			setFilteredItems(
				items.filter(item => item.title.toLowerCase().indexOf(text) !== -1)
			);
		}
		trackEvent('ui', 'searchInputType');
	}

	return (
		<I18n>
			{({ i18n }) => (
				<div
					id="js-saved-items-pane"
					class={`saved-items-pane ${isOpen ? 'is-open' : ''}`}
					onKeyDown={keyDownHandler}
					aria-hidden={isOpen}
				>
					<button
						onClick={onCloseIntent}
						class="btn dialog__close-btn  saved-items-pane__close-btn"
						id="js-saved-items-pane-close-btn"
						aria-label={i18n._(t`Close saved creations pane`)}
					>
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 24 24"
							fill="none"
							stroke="currentColor"
							strokeWidth="3.5"
							strokeLinecap="round"
							strokeLinejoin="round"
						>
							<line x1="18" y1="6" x2="6" y2="18"></line>
							<line x1="6" y1="6" x2="18" y2="18"></line>
						</svg>
					</button>
					<div
						class="flex flex-v-center"
						style="justify-content: space-between;"
					>
						<h3>
							<Trans>My Library ({filteredItems.length})</Trans>
						</h3>

						<div>
							<button
								onClick={onExport}
								class="btn--dark hint--bottom-left hint--rounded hint--medium"
								aria-label={i18n._(
									t`Export all your creations into a single importable file.`
								)}
							>
								<Trans>Export</Trans>
							</button>
							<button
								onClick={importBtnClickHandler}
								class="btn--dark hint--bottom-left hint--rounded hint--medium"
								aria-label={i18n._(
									t`Import your creations. Only the file that you export through the 'Export' button can be imported.`
								)}
							>
								<Trans>Import</Trans>
							</button>
						</div>
					</div>
					<form autoComplete="off" onSubmit={e => e.preventDefault()}>
						<input
							type="search"
							id="searchInput"
							ref={searchInputRef}
							class="search-input"
							onInput={searchInputHandler}
							placeholder={i18n._(t`Search your creations here...`)}
						/>
					</form>

					<div id="js-saved-items-wrap" class="saved-items-pane__container">
						{!filteredItems.length && items.length ? (
							<div class="mt-1">
								<Trans>No match found.</Trans>
							</div>
						) : null}
						{filteredItems.map(item => (
							<ItemTile
								item={item}
								onClick={() => itemClickHandler(item)}
								onForkBtnClick={e => itemForkBtnClickHandler(item, e)}
								onRemoveBtnClick={e => itemRemoveBtnClickHandler(item, e)}
							/>
						))}
						{!items.length ? (
							<div class="tac">
								<h2 class="opacity--30">
									<Trans>Nothing saved here.</Trans>
								</h2>
								<img
									style="max-width: 80%; opacity:0.4"
									src="assets/empty.svg"
								/>
							</div>
						) : null}
					</div>
				</div>
			)}
		</I18n>
	);
}
