'use client';
import * as facelessUIImport from '@faceless-ui/modal';
import React, { useRef, useState } from 'react';
import ReactCrop from 'react-image-crop';
import { editDrawerSlug } from '../../elements/Upload/index.js';
import { Plus } from '../../icons/Plus/index.js';
import { useFormQueryParams } from '../../providers/FormQueryParams/index.js';
import { useTranslation } from '../../providers/Translation/index.js';
import { Button } from '../Button/index.js';
const baseClass = 'edit-upload';
const Input = ({ name, onChange, value })=>/*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__input`
    }, name, /*#__PURE__*/ React.createElement("input", {
        name: name,
        onChange: (e)=>onChange(e.target.value),
        type: "number",
        value: value
    }));
export const EditUpload = ({ fileName, fileSrc, imageCacheTag, showCrop, showFocalPoint })=>{
    const { Modal, useModal } = facelessUIImport;
    const { closeModal } = useModal();
    const { t } = useTranslation();
    const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams();
    const { uploadEdits } = formQueryParams || {};
    const [crop, setCrop] = useState({
        height: uploadEdits?.crop?.height || 100,
        unit: '%',
        width: uploadEdits?.crop?.width || 100,
        x: uploadEdits?.crop?.x || 0,
        y: uploadEdits?.crop?.y || 0
    });
    const [pointPosition, setPointPosition] = useState({
        x: uploadEdits?.focalPoint?.x || 50,
        y: uploadEdits?.focalPoint?.y || 50
    });
    const [checkBounds, setCheckBounds] = useState(false);
    const [originalHeight, setOriginalHeight] = useState(0);
    const [originalWidth, setOriginalWidth] = useState(0);
    const focalWrapRef = useRef();
    const imageRef = useRef();
    const cropRef = useRef();
    const fineTuneCrop = ({ dimension, value })=>{
        const intValue = parseInt(value);
        if (dimension === 'width' && intValue >= originalWidth) return null;
        if (dimension === 'height' && intValue >= originalHeight) return null;
        const percentage = 100 * (intValue / (dimension === 'width' ? originalWidth : originalHeight));
        if (percentage === 100 || percentage === 0) return null;
        setCrop({
            ...crop,
            [dimension]: percentage
        });
    };
    const fineTuneFocalPoint = ({ coordinate, value })=>{
        const intValue = parseInt(value);
        if (intValue >= 0 && intValue <= 100) {
            setPointPosition((prevPosition)=>({
                    ...prevPosition,
                    [coordinate]: intValue
                }));
        }
    };
    const saveEdits = ()=>{
        dispatchFormQueryParams({
            type: 'SET',
            params: {
                uploadEdits: crop || pointPosition ? {
                    crop: crop || null,
                    focalPoint: pointPosition ? pointPosition : null
                } : null
            }
        });
        closeModal(editDrawerSlug);
    };
    const onDragEnd = React.useCallback(({ x, y })=>{
        setPointPosition({
            x,
            y
        });
        setCheckBounds(false);
    }, []);
    const centerFocalPoint = ()=>{
        const containerRect = focalWrapRef.current.getBoundingClientRect();
        const boundsRect = showCrop ? cropRef.current.getBoundingClientRect() : imageRef.current.getBoundingClientRect();
        const xCenter = (boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width * 100;
        const yCenter = (boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height * 100;
        setPointPosition({
            x: xCenter,
            y: yCenter
        });
    };
    const fileSrcToUse = imageCacheTag ? `${fileSrc}?${imageCacheTag}` : fileSrc;
    return /*#__PURE__*/ React.createElement("div", {
        className: baseClass
    }, /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__header`
    }, /*#__PURE__*/ React.createElement("h2", {
        title: `${t('general:editing')} ${fileName}`
    }, t('general:editing'), " ", fileName), /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__actions`
    }, /*#__PURE__*/ React.createElement(Button, {
        "aria-label": t('general:cancel'),
        buttonStyle: "secondary",
        className: `${baseClass}__cancel`,
        onClick: ()=>closeModal(editDrawerSlug)
    }, t('general:cancel')), /*#__PURE__*/ React.createElement(Button, {
        "aria-label": t('general:applyChanges'),
        buttonStyle: "primary",
        className: `${baseClass}__save`,
        onClick: ()=>saveEdits()
    }, t('general:applyChanges')))), /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__toolWrap`
    }, /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__crop`
    }, /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__focal-wrapper`,
        ref: focalWrapRef,
        style: {
            aspectRatio: `${originalWidth / originalHeight}`
        }
    }, showCrop ? /*#__PURE__*/ React.createElement(ReactCrop, {
        className: `${baseClass}__reactCrop`,
        crop: crop,
        onChange: (_, c)=>setCrop(c),
        onComplete: ()=>setCheckBounds(true),
        renderSelectionAddon: ()=>{
            return /*#__PURE__*/ React.createElement("div", {
                className: `${baseClass}__crop-window`,
                ref: cropRef
            });
        }
    }, /*#__PURE__*/ React.createElement("img", {
        alt: t('upload:setCropArea'),
        onLoad: (e)=>{
            setOriginalHeight(e.currentTarget.naturalHeight);
            setOriginalWidth(e.currentTarget.naturalWidth);
        },
        ref: imageRef,
        src: fileSrcToUse
    })) : /*#__PURE__*/ React.createElement("img", {
        alt: t('upload:setFocalPoint'),
        onLoad: (e)=>{
            setOriginalHeight(e.currentTarget.naturalHeight);
            setOriginalWidth(e.currentTarget.naturalWidth);
        },
        ref: imageRef,
        src: fileSrcToUse
    }), showFocalPoint && /*#__PURE__*/ React.createElement(DraggableElement, {
        boundsRef: showCrop ? cropRef : imageRef,
        checkBounds: showCrop ? checkBounds : false,
        className: `${baseClass}__focalPoint`,
        containerRef: focalWrapRef,
        initialPosition: pointPosition,
        onDragEnd: onDragEnd,
        setCheckBounds: showCrop ? setCheckBounds : false
    }, /*#__PURE__*/ React.createElement(Plus, null)))), (showCrop || showFocalPoint) && /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__sidebar`
    }, showCrop && /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__groupWrap`
    }, /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__titleWrap`
    }, /*#__PURE__*/ React.createElement("h3", null, t('upload:crop')), /*#__PURE__*/ React.createElement(Button, {
        buttonStyle: "none",
        className: `${baseClass}__reset`,
        onClick: ()=>setCrop({
                height: 100,
                unit: '%',
                width: 100,
                x: 0,
                y: 0
            })
    }, t('general:reset')))), /*#__PURE__*/ React.createElement("span", {
        className: `${baseClass}__description`
    }, t('upload:cropToolDescription')), /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__inputsWrap`
    }, /*#__PURE__*/ React.createElement(Input, {
        name: `${t('upload:width')} (px)`,
        onChange: (value)=>fineTuneCrop({
                dimension: 'width',
                value
            }),
        value: (crop.width / 100 * originalWidth).toFixed(0)
    }), /*#__PURE__*/ React.createElement(Input, {
        name: `${t('upload:height')} (px)`,
        onChange: (value)=>fineTuneCrop({
                dimension: 'height',
                value
            }),
        value: (crop.height / 100 * originalHeight).toFixed(0)
    }))), showFocalPoint && /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__groupWrap`
    }, /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__titleWrap`
    }, /*#__PURE__*/ React.createElement("h3", null, t('upload:focalPoint')), /*#__PURE__*/ React.createElement(Button, {
        buttonStyle: "none",
        className: `${baseClass}__reset`,
        onClick: centerFocalPoint
    }, t('general:reset')))), /*#__PURE__*/ React.createElement("span", {
        className: `${baseClass}__description`
    }, t('upload:focalPointDescription')), /*#__PURE__*/ React.createElement("div", {
        className: `${baseClass}__inputsWrap`
    }, /*#__PURE__*/ React.createElement(Input, {
        name: "X %",
        onChange: (value)=>fineTuneFocalPoint({
                coordinate: 'x',
                value
            }),
        value: pointPosition.x.toFixed(0)
    }), /*#__PURE__*/ React.createElement(Input, {
        name: "Y %",
        onChange: (value)=>fineTuneFocalPoint({
                coordinate: 'y',
                value
            }),
        value: pointPosition.y.toFixed(0)
    }))))));
};
const DraggableElement = ({ boundsRef, checkBounds, children, className, containerRef, initialPosition = {
    x: 50,
    y: 50
}, onDragEnd, setCheckBounds })=>{
    const [position, setPosition] = useState({
        x: initialPosition.x,
        y: initialPosition.y
    });
    const [isDragging, setIsDragging] = useState(false);
    const dragRef = useRef();
    const getCoordinates = React.useCallback((mouseXArg, mouseYArg, recenter)=>{
        const containerRect = containerRef.current.getBoundingClientRect();
        const boundsRect = boundsRef.current.getBoundingClientRect();
        const mouseX = mouseXArg ?? boundsRect.left;
        const mouseY = mouseYArg ?? boundsRect.top;
        const xOutOfBounds = mouseX < boundsRect.left || mouseX > boundsRect.right;
        const yOutOfBounds = mouseY < boundsRect.top || mouseY > boundsRect.bottom;
        let x = (mouseX - containerRect.left) / containerRect.width * 100;
        let y = (mouseY - containerRect.top) / containerRect.height * 100;
        const xCenter = (boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width * 100;
        const yCenter = (boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height * 100;
        if (xOutOfBounds || yOutOfBounds) {
            setIsDragging(false);
            if (mouseX < boundsRect.left) {
                x = (boundsRect.left - containerRect.left) / containerRect.width * 100;
            } else if (mouseX > boundsRect.right) {
                x = (containerRect.width - (containerRect.right - boundsRect.right)) / containerRect.width * 100;
            }
            if (mouseY < boundsRect.top) {
                y = (boundsRect.top - containerRect.top) / containerRect.height * 100;
            } else if (mouseY > boundsRect.bottom) {
                y = (containerRect.height - (containerRect.bottom - boundsRect.bottom)) / containerRect.height * 100;
            }
            if (recenter) {
                x = xOutOfBounds ? xCenter : x;
                y = yOutOfBounds ? yCenter : y;
            }
        }
        return {
            x,
            y
        };
    }, [
        boundsRef,
        containerRef
    ]);
    const handleMouseDown = (event)=>{
        event.preventDefault();
        setIsDragging(true);
    };
    const handleMouseMove = (event)=>{
        if (!isDragging) return null;
        const { x, y } = getCoordinates(event.clientX, event.clientY);
        setPosition({
            x,
            y
        });
    };
    const onDrop = ()=>{
        setIsDragging(false);
        onDragEnd(position);
    };
    React.useEffect(()=>{
        if (isDragging || !dragRef.current) return;
        if (checkBounds) {
            const { height, left, top, width } = dragRef.current.getBoundingClientRect();
            const { x, y } = getCoordinates(left + width / 2, top + height / 2, true);
            onDragEnd({
                x,
                y
            });
            setPosition({
                x,
                y
            });
            setCheckBounds(false);
            return;
        }
    }, [
        getCoordinates,
        isDragging,
        checkBounds,
        setCheckBounds,
        position.x,
        position.y,
        onDragEnd
    ]);
    React.useEffect(()=>{
        setPosition({
            x: initialPosition.x,
            y: initialPosition.y
        });
    }, [
        initialPosition.x,
        initialPosition.y
    ]);
    return /*#__PURE__*/ React.createElement("div", {
        className: [
            `${baseClass}__draggable-container`,
            isDragging && `${baseClass}__draggable-container--dragging`
        ].filter(Boolean).join(' '),
        onMouseMove: handleMouseMove
    }, /*#__PURE__*/ React.createElement("button", {
        className: [
            `${baseClass}__draggable`,
            className
        ].filter(Boolean).join(' '),
        onMouseDown: handleMouseDown,
        onMouseUp: onDrop,
        ref: dragRef,
        style: {
            left: `${position.x}%`,
            top: `${position.y}%`
        },
        type: "button"
    }, children), /*#__PURE__*/ React.createElement("div", null));
};

//# sourceMappingURL=index.js.map