import { __ } from "@wordpress/i18n";
import {
	useBlockProps,
	InspectorControls,
	MediaUpload,
	MediaUploadCheck,
} from "@wordpress/block-editor";
import {
	PanelBody,
	Button,
	FocalPointPicker,
	RangeControl,
	ToolbarGroup,
	ToolbarButton,
} from "@wordpress/components";
import { BlockControls } from "@wordpress/block-editor";
import { useState } from "@wordpress/element";

import "./editor.scss";

export default function Edit({ attributes, setAttributes }) {
	const { images, height } = attributes;
	const [selectedImageIndex, setSelectedImageIndex] = useState(null);

	const blockProps = useBlockProps();

	const onSelectImages = (media) => {
		const newImages = media.map((img) => ({
			id: img.id,
			url: img.url,
			alt: img.alt || "",
			focalPoint: { x: 0.5, y: 0.5 },
			scale: 0.8,
			rotation: 0,
		}));
		setAttributes({ images: [...images, ...newImages] });
	};

	const updateImageFocalPoint = (index, focalPoint) => {
		const newImages = [...images];
		newImages[index] = { ...newImages[index], focalPoint };
		setAttributes({ images: newImages });
	};

	const updateImageScale = (index, scale) => {
		const newImages = [...images];
		newImages[index] = { ...newImages[index], scale };
		setAttributes({ images: newImages });
	};

	const updateImageRotation = (index, rotation) => {
		const newImages = [...images];
		newImages[index] = { ...newImages[index], rotation };
		setAttributes({ images: newImages });
	};

	const removeImage = (index) => {
		const newImages = images.filter((_, i) => i !== index);
		setAttributes({ images: newImages });
		if (selectedImageIndex === index) {
			setSelectedImageIndex(null);
		}
	};

	const moveImage = (index, direction) => {
		const newImages = [...images];
		const newIndex = index + direction;
		if (newIndex >= 0 && newIndex < images.length) {
			[newImages[index], newImages[newIndex]] = [
				newImages[newIndex],
				newImages[index],
			];
			setAttributes({ images: newImages });
			setSelectedImageIndex(newIndex);
		}
	};

	const getImageStyle = (image) => {
		const focalPoint = image.focalPoint || { x: 0.5, y: 0.5 };
		const scale = image.scale || 0.8;
		const rotation = image.rotation || 0;
		return {
			left: `${focalPoint.x * 100}%`,
			top: `${focalPoint.y * 100}%`,
			transform: ` rotate(${rotation}deg) scale(${scale})`,
		};
	};

	return (
		<>
			<BlockControls>
				<ToolbarGroup>
					<MediaUploadCheck>
						<MediaUpload
							onSelect={onSelectImages}
							allowedTypes={["image"]}
							multiple
							gallery
							value={images.map((img) => img.id)}
							render={({ open }) => (
								<ToolbarButton onClick={open}>
									{__("Add Images", "image-stack")}
								</ToolbarButton>
							)}
						/>
					</MediaUploadCheck>
				</ToolbarGroup>
			</BlockControls>

			<InspectorControls>
				<PanelBody title={__("Container Settings", "image-stack")}>
					<RangeControl
						label={__("Container Height", "image-stack")}
						value={height}
						onChange={(value) => setAttributes({ height: value })}
						min={200}
						max={800}
						step={10}
					/>
				</PanelBody>

				{images.length > 0 && (
					<PanelBody title={__("Images", "image-stack")} initialOpen={true}>
						{images.map((image, index) => (
							<PanelBody
								key={image.id}
								title={`${__("Image", "image-stack")} ${index + 1}`}
								initialOpen={selectedImageIndex === index}
								onToggle={() =>
									setSelectedImageIndex(
										selectedImageIndex === index ? null : index
									)
								}
							>
								<div className="image-stack-image-preview">
									<img src={image.url} alt={image.alt} />
								</div>

								<FocalPointPicker
									label={__("Focal Point", "image-stack")}
									url={image.url}
									value={image.focalPoint || { x: 0.5, y: 0.5 }}
									onChange={(focalPoint) =>
										updateImageFocalPoint(index, focalPoint)
									}
								/>

								<RangeControl
									label={__("Scale", "image-stack")}
									value={image.scale || 0.8}
									onChange={(scale) => updateImageScale(index, scale)}
									min={0.1}
									max={3}
									step={0.05}
								/>

								<RangeControl
									label={__("Rotation (deg)", "image-stack")}
									value={image.rotation || 0}
									onChange={(rotation) => updateImageRotation(index, rotation)}
									min={-180}
									max={180}
									step={1}
								/>

								<div className="image-stack-image-controls">
									<Button
										isSecondary
										isSmall
										disabled={index === 0}
										onClick={() => moveImage(index, -1)}
									>
										{__("↑ Move Up", "image-stack")}
									</Button>
									<Button
										isSecondary
										isSmall
										disabled={index === images.length - 1}
										onClick={() => moveImage(index, 1)}
									>
										{__("↓ Move Down", "image-stack")}
									</Button>
									<Button
										isDestructive
										isSmall
										onClick={() => removeImage(index)}
									>
										{__("Remove", "image-stack")}
									</Button>
								</div>
							</PanelBody>
						))}
					</PanelBody>
				)}
			</InspectorControls>

			<div {...blockProps}>
				<div
					className="image-stack-container"
					style={{ height: `${height}px` }}
				>
					{images.length === 0 && (
						<div className="image-stack-placeholder">
							<MediaUploadCheck>
								<MediaUpload
									onSelect={onSelectImages}
									allowedTypes={["image"]}
									multiple
									gallery
									render={({ open }) => (
										<Button variant="primary" onClick={open}>
											{__("Ajouter une Image", "image-stack")}
										</Button>
									)}
								/>
							</MediaUploadCheck>
						</div>
					)}

					{images.map((image, index) => (
						<div
							key={image.id}
							className={`image-stack-item ${
								selectedImageIndex === index ? "is-selected" : ""
							}`}
							onClick={() => setSelectedImageIndex(index)}
							role="button"
							tabIndex={0}
							onKeyDown={(e) => {
								if (e.key === "Enter" || e.key === " ") {
									setSelectedImageIndex(index);
								}
							}}
							style={getImageStyle(image)}
						>
							<img src={image.url} alt={image.alt} />
						</div>
					))}
				</div>
			</div>
		</>
	);
}
