import { __, sprintf, _n } from '@wordpress/i18n';
import { useEntityProp } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import React, { useState } from 'react';
import {
	Button,
	TextControl,
	ToggleControl,
	SelectControl,
} from '@wordpress/components';

import { reset } from '@wordpress/icons';

import SidebarCollapsible from './SidebarCollapsible';

export default function WEVCPlayback(props) {
	// put defaults in props!
	// get set state locally
	const postType = useSelect(
		(select) => select('core/editor').getCurrentPostType(),
		[]
	);

	// Get the value of meta and a function for updating meta from useEntityProp.
	const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
	const metaAutoplay = 'wevideopopup_autoplay';
	const metaDelay = 'wevideopopup_delay';
	const metaMute = 'wevideopopup_mute';
	const metaLaunchclass = 'wevideopopup_launchclass';
	const metaPopup = 'wevideopopup_popup';
	const metaControls = 'wevideopopup_controls';

	const metaFrequencyPeriod = 'wevideopopupFrequencyPeriod';
	const metaFrequencyRange = 'wevideopopupFrequencyRange';

	/**
	 * A helper function for getting post meta by key.
	 *
	 * @param {string} key - The meta key to read.
	 * @return {*} - Meta value.
	 */
	const getPostMeta = (key) => meta[key] || '';
	/**
	 * A helper function for updating post meta that accepts a meta key and meta
	 * value rather than entirely new meta object.
	 *
	 * Important! Don't forget to register_post_meta (see ../index.php).
	 *
	 * @param {string} key   - The meta key to update.
	 * @param {*}      value - The meta value to update.
	 */
	const setPostMeta = (key, value) =>
		setMeta({
			...meta,
			[key]: value,
		});
	const isTrue = (val) => {
		return val === '1' || val === true || val === 'true';
	};
	// state - either from meta or from props if not set
	const [selectedAutoplay, setSelectedAutoplay] = useState(() => {
		const postMeta = getPostMeta(metaAutoplay);
		if (postMeta !== '') {
			return isTrue(postMeta) ? true : false;
		}
		return props.default_autoplay;
	});
	const [selectedDelay, setSelectedDelay] = useState(
		getPostMeta(metaDelay) !== ''
			? getPostMeta(metaDelay)
			: props.default_delay
	);
	const [selectedFrequencyPeriod, setSelectedFrequencyPeriod] = useState(
		getPostMeta(metaFrequencyPeriod) !== ''
			? getPostMeta(metaFrequencyPeriod)
			: props.defaultFrequencyPeriod
	);
	const [selectedFrequencyRange, setSelectedFrequencyRange] = useState(
		getPostMeta(metaFrequencyRange) !== ''
			? getPostMeta(metaFrequencyRange)
			: props.defaultFrequencyRange
	);
	const [selectedMute, setSelectedMute] = useState(() => {
		const postMeta = getPostMeta(metaMute);
		if (postMeta !== '') {
			return isTrue(postMeta);
		}
		return props.default_mute;
	});
	const [selectedLaunchclass, setSelectedLaunchClass] = useState(
		getPostMeta(metaLaunchclass) !== ''
			? getPostMeta(metaLaunchclass)
			: props.default_launchclass
	);
	const [selectedControls, setSelectedControls] = useState(
		getPostMeta(metaControls) !== ''
			? isTrue(getPostMeta(metaControls))
			: props.default_controls
	);
	const [selectedPopup, setSelectedPopup] = useState(
		getPostMeta(metaPopup) !== ''
			? isTrue(getPostMeta(metaPopup))
			: props.default_popup
	);

	const revert = () => {
		// trigger handlers with defaults
		setSelectedAutoplay(props.default_autoplay);
		setSelectedMute(props.default_mute);
		setSelectedDelay(props.default_delay);
		setSelectedFrequencyPeriod(props.defaultFrequencyPeriod);
		setSelectedFrequencyRange(props.defaultFrequencyRange);

		handleLaunchclass(props.default_launchclass);
		handlePopup(props.default_popup);
		handleControls(props.default_controls);

		// This works... but might need to tidy up
		setMeta({
			...meta,
			[metaAutoplay]: props.default_autoplay ? '1' : '0',
			[metaMute]: props.default_mute ? '1' : '0',
			[metaDelay]: props.default_delay,
			[metaFrequencyPeriod]: String(props.defaultFrequencyPeriod),
			[metaFrequencyRange]: props.defaultFrequencyRange,
			[metaLaunchclass]: props.default_launchclass,
			[metaControls]: props.default_controls,
		});
	};
	// convieneince method to check if the current settings are the defaults
	const isDefault = () => {
		return (
			props.default_autoplay === selectedAutoplay &&
			props.default_delay === selectedDelay &&
			((selectedFrequencyPeriod === props.defaultFrequencyPeriod &&
				selectedFrequencyPeriod === 0) ||
				(selectedFrequencyRange === props.defaultFrequencyRange &&
					selectedFrequencyPeriod ===
						props.defaultFrequencyPeriod)) &&
			// mute
			props.default_mute === selectedMute &&
			props.default_launchclass === selectedLaunchclass &&
			props.default_popup === selectedPopup &&
			props.default_controls === selectedControls
		);
	};
	const handleAutoplay = (show) => {
		setSelectedAutoplay(show);
		const val = show ? '1' : '0'; // converting to a string
		setPostMeta(metaAutoplay, val);
	};
	const handleMute = (show) => {
		setSelectedMute(show);
		const val = show ? '1' : '0'; // converting to a string
		setPostMeta(metaMute, val);
	};
	const handleDelay = (value) => {
		setSelectedDelay(value);
		setPostMeta(metaDelay, value);
	};
	const handlePeriod = (value) => {
		setSelectedFrequencyPeriod(value);
		setPostMeta(metaFrequencyPeriod, value);
		if (value === '0') {
			handleRange(0);
		}
	};
	const handleRange = (value) => {
		setSelectedFrequencyRange(value);
		setPostMeta(metaFrequencyRange, value);
	};
	const handleLaunchclass = (value) => {
		setSelectedLaunchClass(value);
		setPostMeta(metaLaunchclass, value);
	};
	const handleControls = (value) => {
		setSelectedControls(value);
		const val = value ? '1' : '0';
		setPostMeta(metaControls, val);
	};
	const handlePopup = (value) => {
		setSelectedPopup(value);
		setPostMeta(metaPopup, value ? '1' : '0');
	};
	/**
	 * @param {string} p The period value.
	 * @return {string} The wordy equivalent of the period.
	 */
	const getFrequencyHelperText = (p) => {
		// nest switches for plural and non-plural - then we have translation strings for every language
		let str = '';
		if (selectedFrequencyPeriod === 0) {
			str = __('Always show', 'video-callout');
		} else {
			const thisDefault =
				(selectedFrequencyPeriod === props.defaultFrequencyPeriod &&
					selectedFrequencyPeriod === 0) ||
				(selectedFrequencyRange === props.defaultFrequencyRange &&
					selectedFrequencyPeriod === props.defaultFrequencyPeriod);
			const range = parseInt(selectedFrequencyRange);

			if (selectedFrequencyRange > 0) {
				// wait for
				// xxx
				// before redisplay
				// (default) ?
				if (thisDefault) {
					switch (parseInt(p)) {
						case 1:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d second before redisplay (default)',
									'Wait for %d seconds before redisplay (default)',
									range,
									'video-callout'
								),
								range
							);
						case 2:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d minute before redisplay (default)',
									'Wait for %d minutes before redisplay (default)',
									range,
									'video-callout'
								),
								range
							);
						case 3:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d hour before redisplay (default)',
									'Wait for %d hours before redisplay (default)',
									range,
									'video-callout'
								),
								range
							);
						case 4:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d day before redisplay (default)',
									'Wait for %d days before redisplay (default)',
									range,
									'video-callout'
								),
								range
							);
					}
				} else {
					switch (parseInt(p)) {
						case 1:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d second before redisplay',
									'Wait for %d seconds before redisplay',
									range,
									'video-callout'
								),
								range
							);
						case 2:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d minute before redisplay',
									'Wait for %d minutes before redisplay',
									range,
									'video-callout'
								),
								range
							);
						case 3:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d hour before redisplay',
									'Wait for %d hours before redisplay',
									range,
									'video-callout'
								),
								range
							);
						case 4:
							return sprintf(
								/* translators: %d: number of seconds, minutes, hours, or days */
								_n(
									'Wait for %d day before redisplay',
									'Wait for %d days before redisplay',
									range,
									'video-callout'
								),
								range
							);
					}
				}
			} else {
				//how many
				switch (parseInt(p)) {
					case 1:
						return __(
							'How many seconds before redisplay',
							'video-callout'
						);
					case 2:
						return __(
							'How many minutes before redisplay',
							'video-callout'
						);
					case 3:
						return __(
							'How many hours before redisplay',
							'video-callout'
						);
					case 4:
						return __(
							'How many days before redisplay',
							'video-callout'
						);
				}
			}
		}

		return str;
	};
	const getFrequencyOptions = (r) => {
		if (r > 1) {
			return [
				{
					label: __('Always show', 'video-callout'),
					value: 0,
				},
				{
					label: __('Seconds', 'video-callout'),
					value: 1,
				},
				{
					label: __('Minutes', 'video-callout'),
					value: 2,
				},
				{
					label: __('Hours', 'video-callout'),
					value: 3,
				},
				{
					label: __('Days', 'video-callout'),
					value: 4,
				},
			];
		}
		return [
			{
				label: __('Always show', 'video-callout'),
				value: 0,
			},
			{
				label: __('Second', 'video-callout'),
				value: 1,
			},
			{
				label: __('Minute', 'video-callout'),
				value: 2,
			},
			{
				label: __('Hour', 'video-callout'),
				value: 3,
			},
			{
				label: __('Day', 'video-callout'),
				value: 4,
			},
		];
	};
	return (
		<SidebarCollapsible
			icon={'admin-settings'}
			title={__('Playback', 'video-callout')}
		>
			<ToggleControl
				name="wevideopopup_autoplay"
				label={__('Autoplay', 'video-callout')}
				help={
					(selectedAutoplay
						? __(
								'Will attempt to autoplay on load. Video must be muted for autoplay to work in some browsers.',
								'video-callout'
							) + ' Google drive videos cannot be autoplayed.'
						: __('Autoplay off', 'video-callout')) +
					(selectedAutoplay === props.default_autoplay
						? ' (' + __('default', 'video-callout') + ')'
						: '')
				}
				checked={selectedAutoplay}
				onChange={handleAutoplay}
			/>
			<ToggleControl
				name="wevideopopup_popup"
				label={__('Launch on page load', 'video-callout')}
				help={__(
					'Video callout will be launched on page load. Otherwise you will have to specifiy a launch class below.',
					'video-callout'
				)}
				checked={selectedPopup}
				onChange={handlePopup}
			/>
			<TextControl
				name="wevideopopup_launchclass"
				label={__('Element launch class', 'video-callout')}
				value={selectedLaunchclass}
				onChange={handleLaunchclass}
				help={__(
					'Optional: Elements containing this class can launch the callout when clicked. There will be no delay.',
					'video-callout'
				)}
			/>
			<TextControl
				name="wevideopopup_delay"
				label={__('Delay', 'video-callout')}
				value={selectedDelay}
				type="number"
				onChange={handleDelay}
				className={
					getPostMeta(metaDelay) === '' ||
					props.default_delay === selectedDelay
						? 'wevc-default'
						: 'wevc-non-default'
				}
				help={
					__(
						'Number of milliseconds until video appears, 1000 = 1 second',
						'video-callout'
					) +
					(props.default_delay === selectedDelay
						? ' (' + __('default', 'video-callout') + ')'
						: '')
				}
			/>

			<>
				{(!selectedFrequencyPeriod ||
					selectedFrequencyPeriod === 0 ||
					selectedFrequencyPeriod < 1) && (
					<>
						<SelectControl
							label={__('Frequency', 'video-callout')}
							onChange={handlePeriod}
							value={selectedFrequencyPeriod}
							options={getFrequencyOptions(
								selectedFrequencyRange
							)}
							className={
								selectedFrequencyPeriod === '' ||
								props.defaultFrequencyPeriod ===
									selectedFrequencyPeriod
									? 'wevc-default'
									: 'wevc-non-default'
							}
							help={getFrequencyHelperText(
								selectedFrequencyPeriod
							)}
						/>
					</>
				)}
				{selectedFrequencyPeriod > 0 && (
					<>
						<SelectControl
							label={__('Frequency', 'video-callout')}
							onChange={handlePeriod}
							value={selectedFrequencyPeriod}
							options={getFrequencyOptions(
								selectedFrequencyRange
							)}
							className={
								selectedFrequencyPeriod === '' ||
								props.defaultFrequencyPeriod ===
									selectedFrequencyPeriod
									? 'wevc-default'
									: 'wevc-non-default'
							}
						/>

						<TextControl
							// max={2147483647}
							// min={0}
							// value={range}
							type="number"
							value={
								Math.min(
									Math.max(
										0,
										parseInt(selectedFrequencyRange)
									),
									2147483647
								) || 0
							}
							onChange={handleRange}
							help={getFrequencyHelperText(
								selectedFrequencyPeriod
							)}
							className={
								selectedFrequencyRange === '' ||
								props.defaultFrequencyRange ===
									selectedFrequencyRange
									? 'wevc-default'
									: 'wevc-non-default'
							}
						/>
					</>
				)}
			</>

			<ToggleControl
				label={__('Mute', 'video-callout')}
				help={
					(selectedMute ? 'Audio off' : 'Audio on') +
					(selectedMute === props.default_mute
						? ' (' + __('default', 'video-callout') + ')'
						: '')
				}
				name="wevideopopup_mute"
				checked={selectedMute}
				onChange={handleMute}
			/>
			{/* onChange={(show) => setPostMeta(metaMute, show ? "1" : "0")} /> */}

			<ToggleControl
				name="wevideopopup_controls"
				label={__('Show player controls', 'video-callout')}
				help={
					selectedControls
						? 'Controls on'
						: 'Controls off - Vimeo will need autoplay enabled or played from keyboard shortcut. Google drive does not support hiding controls.'
				}
				checked={selectedControls}
				onChange={handleControls}
			/>

			{!isDefault() && (
				<Button isSmall variant="primary" icon={reset} onClick={revert}>
					{__('Revert playback to defaults', 'video-callout')}
				</Button>
			)}
		</SidebarCollapsible>
	);
}
