import { BlockControls, InspectorControls } from '@wordpress/block-editor';
import { PanelBody } from '@wordpress/components';
import { Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { FloRangeControl, RadioImageControl } from 'components';
import 'lazysizes';
import {
	GalleryGridControls,
	GalleryGridView,
} from './components/GalleryGrid/GalleryGridEdit';
import {
	GallerySliderControl,
	GallerySliderView,
	unslick,
} from './components/GallerySlider/GallerySliderEdit';
import { GalleryMediaPlaceholder } from './controls/mediaPlaceholder/GalleryMediaPlaceholder';
import { MediaUploadToolbar } from './controls/mediaUploadTolbar/MediaUploadToolbar';
import { GallerySource } from './components/GallerySource/GallerySource';


let placeholdersSet = false;
export default function Edit(props) {
	const { attributes } = props;
	const {
		images,
		ids,
		galleryType,
		sliderType,
		sliderHeight,
		topMargin,
		bottomMargin,
		mobileTopMargin,
		mobileBottomMargin,
		sliderMobileHeight,
		itemsGap,
		itemsGapMobile,
		imagesSource,
		imagesSourceGalleryID
	} = attributes;

	/**
	 * If we are on custom Template Post type page, then we need to change the behaviour for this block:
	 * - 	When the  block is added to a template, the upload images buttons  will disappear and  instead we will  have just some images placeholders.
	 *		And the user will be  able to adjust the settings.
	 *		In  this  case the block will take the images from the post meta(the same as the  current themes)
	 *		'isTemplateBlock' - Also add a new attribute to the block that will act as a flag to let us know that we need  to use  the images from the  meta.
	 */

	if (
		fgb_blocks_info.is_g_template_post_screen === 'true' &&
		!placeholdersSet
	) {
		placeholdersSet = true;
		// is_template_post_screen is localized by PHP
		// plugin_root is localized from PHP
		const prependUrl = (u) => fgb_blocks_info.plugin_root + u; // take the given URL and prepend the plugin root URL

		let placeholderImages = require('./utils/placeholder-images.json');

		// replacing the images with the hardcoded place holders
		// we need to interate through this  array and modify the 'url' and 'thumbnail' properties
		props.setAttributes({
			images: placeholderImages.map((img) => ({
				...img,
				url: prependUrl(img.url),
				thumbnail: prependUrl(img.thumbnail),
			})),
			ids: placeholderImages.map((img) => ({
				id: img.id,
			})),
			isTemplateBlock: true,
		});
	}

	const pickRelevantMediaFiles = (image) => {
		const imageProps = {
			url: image.sizes?.full?.url || image.url,
			thumbnail: image.sizes?.thumbnail?.url || image.url,
			alt: image.alt,
			caption: image.caption,
			id: image.id,
			type: image.type,
			width: image.sizes?.full?.width || image.width,
			height: image.sizes?.full?.height || image.height,
		};
		return imageProps;
	};
	const pickRelevantIDs = (image) => {
		return image.id;
	};
	const onSelectImages = (images) => {
		unslick(props);

		props.setAttributes({
			images: images.map((image) => pickRelevantMediaFiles(image)),
			ids: images.map((image) => pickRelevantIDs(image)),
		});

	};
	const setAttributes = (attributes) => {
		props.setAttributes(attributes);
	};

	/**
	 * Use as the source for the images the meta data of the given Gallery post
	*/
	const setImagesSourceToGallery = (gallery_id) => {
		gallery_id = parseInt(gallery_id);

		if (gallery_id > 0) {
			jQuery('.flo-dd-spinner').css('visibility', 'visible');

			// fgb_blocks_info.galleries_with_meta_images is localized
			// we want to find the gallery with the ID = value
			let filterObj = fgb_blocks_info.galleries_with_meta_images.filter(function (e) {
				return e.value === parseInt(gallery_id);
			});

			// The media IDs for the selected Gallery post
			let mediaIDs = Object.values(filterObj[0]?.meta);

			console.log('typeof meta', mediaIDs);

			let galleryImagesCollection = [];

			// fetch Media one by one, and all the requests are done, we update the attributes
			const fetchMedia = (mediaID, collectionArray, expectedSize) => {

				// get the media info by ID
				let the_media = new wp.api.models.Media({ id: mediaID });

				the_media?.fetch().then(response => {
					//console.log('media response',response);
					collectionArray.push(response);

					// this verification makes sure all the requests have finalized
					if (collectionArray.length === expectedSize) {
						jQuery('.flo-dd-spinner').css('visibility', 'hidden');
						updateAttributes(collectionArray);
					}
				});

			}

			mediaIDs.forEach(media_item => {
				fetchMedia(media_item, galleryImagesCollection, mediaIDs.length)
			});



			const updateAttributes = (images) => {
				if (images) {
					const correctedImages = images.map(image => {
						// the returned object has a different structure, therefore we will populate the missing fields
						let img = { ...image, url: image.source_url, alt: image.alt_text, height: image.media_details.height, width: image.media_details.width, sizes: image.media_details.sizes }

						return img;
					});

					onSelectImages(correctedImages); // update the images and ids attributes
					setAttributes({ imagesSourceGalleryID: gallery_id, imagesSource: 'gallery' });
				}
			}

		} else { // if gallery_id == 0
			onSelectImages([]); // update the images and ids attributes
			setAttributes({ imagesSourceGalleryID: gallery_id, imagesSource: 'media_library' });
		}

	}

	const setSliderType = (value) => {
		setAttributes({ sliderType: value });
		unslick(props);
		if (value === 'multiple_items') {
			if (images.length > 3) {
				setAttributes({
					slidesToShow: 1,
					variableWidth: true,
					fade: false,
				});
			} else {
				setAttributes({
					slidesToShow: 3,
					variableWidth: true,
					fade: false,
					centerMode: true,
				});
			}

			if ('full' !== props.attributes.align) {
				setAttributes({ align: 'full' });
			}
		}

		if (value === 'singleitem') {
			setAttributes({
				slidesToShow: 1,
				variableWidth: false,
				centerMode: true,
			});

			if ('full' === props.attributes.align) {
				setAttributes({ align: '' });
			}
		}
	};
	const setSliderHeight = (height) => {
		let un_slick = false;
		props.setAttributes({ sliderHeight: height }, un_slick);
	};


	const hasImages = () => (
		<Fragment>
			<BlockControls>
				{(!(imagesSource === 'gallery' && imagesSourceGalleryID > 0) && images.length) &&
					fgb_blocks_info.is_template_post_screen !== 'true' && (
					<MediaUploadToolbar {...props} onSelectImages={onSelectImages} />
				)}
			</BlockControls>

			<InspectorControls>
				{!!Object.keys(fgb_blocks_info.galleries_with_meta_images).length && (

					<GallerySource {...props} setImagesSourceToGallery={setImagesSourceToGallery} />
				)}

				<PanelBody title={__('Layout')} initialOpen={true}>
					<RadioImageControl
						label="Gallery view"
						classNameProp="flo-gallery-type"
						options={[
							{
								value: 'slider',
								label: 'Slider',
								preview: `${fgb_blocks_info.plugin_root}images/visible-nearby-slides.jpg`,
							},
							{
								value: 'grid',
								label: 'Grid',
								preview: `${fgb_blocks_info.plugin_root}images/gallery-grid.jpg`,
							},
						]}
						selected={galleryType}
						onChange={(value) => {
							setAttributes({ galleryType: value });
							if (value === 'slider') {
								setSliderType('singleitem');
							}
							if (value === 'grid') {
								if ('full' === props.attributes.align) {
									setAttributes({ align: '' });
								}
							}
						}}
					/>
					{galleryType === 'slider' && (
						<RadioImageControl
							label="Slider type"
							classNameProp="flo-gallery-type"
							options={[
								{
									value: 'singleitem',
									label: __('Single Slide'),
									preview: `${fgb_blocks_info.plugin_root}images/single-slider.jpg`,
								},
								{
									value: 'multiple_items',
									label: __('Visible Nearby'),
									preview: `${fgb_blocks_info.plugin_root}images/visible-nearby-slides.jpg`,
								},
							]}
							selected={sliderType}
							onChange={(value) => {
								setSliderType(value);
							}}
						/>
					)}
					{galleryType === 'slider' && (
						<FloRangeControl
							label={__('Desktop Image Height', 'flo')}
							value={sliderHeight}
							onChange={(value) => {
								setSliderHeight(value);
							}}
							min={1}
							max={800}
							unit={__('PX', 'flo')}
						/>
					)}
					{galleryType === 'slider' && (
						<FloRangeControl
							label={__('Mobile Image Height', 'flo')}
							value={sliderMobileHeight}
							onChange={(value) => {
								setAttributes({ sliderMobileHeight: value });
							}}
							min={1}
							max={500}
							unit={__('PX', 'flo')}
						/>
					)}
					{/*sliderType === 'multiple_items' && galleryType === 'slider' && (
						<FloToggleControl
							label={__('Image Center Mode', 'flo')}
							checked={!!centerMode}
							onChange={(value) => {
								setAttributes({centerMode: value});
							}}
						/>
						)*/}
					{galleryType === 'slider' && sliderType === 'multiple_items' && (
						<FloRangeControl
							label={__('Gap Desktop', 'flo')}
							value={itemsGap}
							onChange={(value) => {
								setAttributes({ itemsGap: value });
							}}
							min={0}
							max={100}
							unit={__('PX', 'flo')}
						/>
					)}

					{galleryType === 'slider' && sliderType === 'multiple_items' && (
						<FloRangeControl
							label={__('Gap Mobile', 'flo')}
							value={itemsGapMobile}
							onChange={(value) => {
								setAttributes({ itemsGapMobile: value }, false);
							}}
							min={0}
							max={50}
							unit={__('PX', 'flo')}
						/>
					)}
					{galleryType === 'grid' && <GalleryGridControls {...props} />}
				</PanelBody>
				{galleryType === 'slider' && <GallerySliderControl {...props} />}

				<PanelBody title={__('Margins')} initialOpen={false}>
					<p>{__('Desktop')}</p>
					<FloRangeControl
						label={__('Top', 'flo')}
						value={topMargin}
						onChange={(val) => setAttributes({ topMargin: val })}
						min={-100}
						max={100}
						unit={__('PX', 'flo')}
					/>
					<FloRangeControl
						label={__('Bottom', 'flo')}
						value={bottomMargin}
						onChange={(val) => setAttributes({ bottomMargin: val })}
						min={-100}
						max={100}
						unit={__('PX', 'flo')}
					/>
					<p>{__('Mobile')}</p>
					<FloRangeControl
						label={__('Top', 'flo')}
						value={mobileTopMargin}
						onChange={(val) => setAttributes({ mobileTopMargin: val })}
						min={-100}
						max={100}
						unit={__('PX', 'flo')}
					/>
					<FloRangeControl
						label={__('Bottom', 'flo')}
						value={mobileBottomMargin}
						onChange={(val) => setAttributes({ mobileBottomMargin: val })}
						min={-100}
						max={100}
						unit={__('PX', 'flo')}
					/>
				</PanelBody>
			</InspectorControls>
			{galleryType === 'slider' && <GallerySliderView {...props} />}
			{galleryType === 'grid' && <GalleryGridView {...props} />}
		</Fragment>
	);

	const noimages = () => (
		<Fragment>
			<GalleryMediaPlaceholder {...props} onSelectImages={onSelectImages} setImagesSourceToGallery={setImagesSourceToGallery} />
		</Fragment>
	);

	return (ids.length || (imagesSource === 'gallery' && imagesSourceGalleryID > 0)) ? hasImages() : noimages();
}
