import "./editor.scss";
import "./focus-point";

import { __ } from "@wordpress/i18n";
import { useSelect, dispatch, select } from "@wordpress/data";
import { useEffect, useState } from "@wordpress/element";
import { createBlock } from "@wordpress/blocks";

import {
	InnerBlocks,
	useBlockProps,
	MediaPlaceholder,
	BlockControls,
	MediaReplaceFlow,
	InspectorControls,
} from "@wordpress/block-editor";
import {
	ToggleControl,
	ToolbarButton,
	Spinner,
	withNotices,
	Button,
	PanelBody,
	Tip,
} from "@wordpress/components";

import { isBlobURL, revokeBlobURL } from "@wordpress/blob";
import { cover, handle, trash } from "@wordpress/icons";

function Edit({
	attributes,
	setAttributes,
	noticeOperations,
	noticeList,
	noticeUI,
	clientId,
	...props
}) {
	const {
		coverUrl,
		coverId,
		coverAlt,
		showLegend,
		coverLegend,
		showDescription,
		coverDescription,
		focusBullets,
	} = attributes;

	const [blobUrl, setBlobUrl] = useState();
	const currentBlockDatas = useSelect((select) => {
		return select("core/block-editor").getBlocksByClientId(clientId)[0];
	});

	let children = useSelect(
		(select) =>
			select("core/block-editor").getBlocksByClientId(clientId)[0].innerBlocks
	);

	function onUploadError(message) {
		noticeOperations.removeAllNotices(); // Remove all previous notices
		noticeOperations.createErrorNotice(message);
	}

	function removeCoverImg() {
		setAttributes({
			coverUrl: undefined,
			coverId: undefined,
			coverDescription: "",
			coverLegend: "",
			coverAlt: "",
		});
	}

	function updateCover(image) {
		if (!image || !image.url) {
			setAttributes({
				coverUrl: undefined,
				coverId: undefined,
				coverDescription: "",
				coverLegend: "",
				coverAlt: "",
			});
			return;
		}
		setAttributes({
			coverUrl: image.url,
			coverId: image.id,
			coverAlt: image.alt,
			coverDescription: image.description,
			coverLegend: image.caption,
		});
	}

	function passCoverUrlToChildren() {
		if (children && coverUrl) {
			children.forEach(function (child) {
				dispatch("core/block-editor").updateBlockAttributes(child.clientId, {
					coverUrl: coverUrl,
				});
			});
		}
	}

	function passIndexToChildren() {
		if (children) {
			children.forEach((child, index) => {
				dispatch("core/block-editor").updateBlockAttributes(child.clientId, {
					focusIndex: index + 1,
				});
			});
		}
	}

	function updateFocusPointBullets() {
		if (children) {
			const focusBullets = children.map((child, index) => {
				return {
					title: child.attributes.focusTitle,
					x: child.attributes.focusPosition.x,
					y: child.attributes.focusPosition.y,
				};
			});

			setAttributes({ focusBullets });
		}
	}

	function insertFocusPointBlock() {
		const index = children && children.length ? children.length : 0;
		const newBlock = createBlock("homegrade-content-blocks/focus-point", {});
		dispatch("core/block-editor").insertBlocks(newBlock, index, clientId);
	}

	function handleBulletClick(index) {
		if (currentBlockDatas && currentBlockDatas.innerBlocks) {
			dispatch("core/block-editor").selectBlock(
				currentBlockDatas.innerBlocks[index].clientId
			);
		}
	}

	function handleShowDescription() {
		setAttributes({ showDescription: !showDescription });
	}
	function handleShowLegend() {
		setAttributes({ showLegend: !showLegend });
	}

	const renderedFocusPointBullets = focusBullets.map((focusBullet, index) => {
		return (
			<div
				data-focus-bullet-title={focusBullet.title}
				className="homegrade-blocks-focus-point-bullet"
				style={{
					top: `${focusBullet.y * 100}%`,
					left: `${focusBullet.x * 100}%`,
				}}
				onClick={() => handleBulletClick(index)}
			>
				<span className="homegrade-blocks-focus-point-bullet__index">
					{index + 1}
				</span>
			</div>
		);
	});

	useEffect(() => {
		updateFocusPointBullets();
		if (!coverId && isBlobURL(coverUrl)) {
			setAttributes({ coverUrl: undefined, coverAlt: "" });
		}
	}, []);
	useEffect(() => {
		// Fonction de clean du BLOB URL qui se lance à chaque changement de coverUrl
		if (isBlobURL(coverUrl)) {
			// Si la cover est une blob, c'est que ça upload donc on met cette url dans le state
			setBlobUrl(coverUrl);
		} else {
			// Si la cover en'est plus une blob, c'est que l'upload est terminé, on revoke la blob et on clean le state
			revokeBlobURL(blobUrl); // On utilise la valeur stocké dans le state pour revoke l'url
			setBlobUrl();
		}
		passCoverUrlToChildren();
	}, [coverUrl]);

	useEffect(() => {
		updateFocusPointBullets();
		passCoverUrlToChildren();
	}, [children]);
	useEffect(() => {
		passIndexToChildren();
	}, [currentBlockDatas]);

	return (
		<>
			<InspectorControls>
				<PanelBody title="Points de légende">
					<Button
						variant="primary"
						onClick={() => {
							insertFocusPointBlock();
						}}
					>
						Ajouter un point Légende
					</Button>
				</PanelBody>
				<PanelBody
					title="Source de l'image / Schéma"
					className="homegrade-blocks-components-image__panel-body "
				>
					{coverUrl && <img src={coverUrl} alt={coverAlt} />}
					<div className="media-replace-container">
						<MediaReplaceFlow
							mediaId={coverId}
							mediaUrl={coverUrl}
							allowedTypes={["image"]}
							accept="image/*"
							onSelect={updateCover}
							name={
								!coverUrl
									? __("Ajouter", "homegrade-blocks__texte-backoffice")
									: __("Remplacer", "homegrade-blocks__texte-backoffice")
							}
						/>
						{coverUrl && (
							<div>
								<Button
									className="custom-flow-button"
									variant="primary"
									icon={trash}
									label="Supprimer"
									onClick={removeCoverImg}
								/>
							</div>
						)}
					</div>
				</PanelBody>

				<PanelBody
					title="Paramètres"
					className="homegrade-blocks-components-image__panel-body "
				>
					<ToggleControl
						label="Afficher la description"
						checked={showDescription}
						onChange={handleShowDescription}
						help="Coché, la description sera ajouté sous l'image"
					/>
					<ToggleControl
						label="Afficher la légende"
						checked={showLegend}
						onChange={handleShowLegend}
						help="Coché, la légende (caption) sera ajouté sous l'image"
					/>
				</PanelBody>
			</InspectorControls>

			<MediaPlaceholder
				disableMediaButtons={coverUrl}
				icon="admin-appearance"
				onSelect={updateCover}
				onError={onUploadError}
				accept="image/*" // On upload Allow only images
				allowedTypes={["image"]} // Onlibrary Allow only images
				notices={noticeUI} // En cas d'erreur d'upload
			/>
			<section
				{...useBlockProps({
					className: `homegrade-blocks-focused-schema`,
				})}
			>
				{coverUrl && (
					<figure
						className={`picture-container ${
							isBlobURL(coverUrl) ? "is-loading" : ""
						}`}
					>
						<img
							src={coverUrl}
							alt={coverAlt}
							data-description={coverDescription}
							data-legend={coverLegend}
						/>
						{renderedFocusPointBullets}
						{isBlobURL(coverUrl) && <Spinner />}
					</figure>
				)}

				<figcaption>
					<p className="description-legend">
						{showLegend && coverLegend && (
							<span className="legend">{coverLegend}</span>
						)}
						{showDescription && coverDescription && (
							<span className="description">{coverDescription}</span>
						)}
					</p>
					<ol>
						<InnerBlocks
							allowedBlocks={["homegrade-content-blocks/focus-point"]}
						/>
					</ol>
				</figcaption>
			</section>
		</>
	);
}

export default withNotices(Edit);
