import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from "react";
import { useEditContext, useEditContextRef } from "./client/editContext";
import { PictureCropper } from "./PictureCropper";
import { loadFieldButtons } from "./services/editService";
import { FieldActionsOverlay, } from "./FieldActionsOverlay";
import { ImageEditButton } from "./ImageEditButton";
import { MagicEditImageIcon } from "./ui/Icons";
import { Settings, Zap, Sparkles } from "lucide-react";
import { AiImageEditorDialog } from "./ai-image-editor";
import { toast } from "sonner";
import { LicenseFeatures, useFeature } from "../licensing";
import { canCropPictureFieldRawValue, tryParsePictureRawValue, } from "./pictureRawValue";
export function PictureEditor({ field, variantName, style, forwardScrollevents, isPageEditor, onContextMenu, onDialogOpenChange, }) {
    const [showCropper, setShowCropper] = useState(false);
    const [isMenuOpen, setIsMenuOpen] = useState(false);
    const [isOverlayOpen, setIsOverlayOpen] = useState(false);
    const [fieldButtons, setFieldButtons] = useState([]);
    const [variantButtons, setVariantButtons] = useState([]);
    const fieldActionsOverlay = useRef(null);
    const editContext = useEditContext();
    const editContextRef = useEditContextRef();
    const editorIframe = editContext?.getActiveSlotContext()?.primaryPageViewContext.editorIframe;
    const canUseAi = useFeature(LicenseFeatures.AI);
    // AI Image Editor state
    const [showAiImageEditor, setShowAiImageEditor] = useState(false);
    const [aiEditOriginalRawValue, setAiEditOriginalRawValue] = useState(null);
    // Notify parent when dialog (cropper), menu or overlay opens/closes
    useEffect(() => {
        onDialogOpenChange?.(showCropper || isMenuOpen || isOverlayOpen || showAiImageEditor);
    }, [showCropper, isMenuOpen, isOverlayOpen, showAiImageEditor, onDialogOpenChange]);
    // Handle opening AI image editor
    const handleOpenAiImageEditor = useCallback(() => {
        // Store original value for potential revert
        setAiEditOriginalRawValue(field.rawValue || "");
        setShowAiImageEditor(true);
    }, [field.rawValue]);
    const handleOpenCropper = useCallback(() => {
        if (!canCropPictureFieldRawValue(field.rawValue)) {
            toast.warning("Crop isn't available while this picture field is stored as a basic image value.");
            return;
        }
        setShowCropper(true);
    }, [field.rawValue]);
    // Handle AI edit complete - triggers field action for progress indication
    const handleAiEditComplete = useCallback((result) => {
        setShowAiImageEditor(false);
        const ctx = editContextRef.current;
        if (result.success && ctx) {
            // Trigger field action to show progress indicator on the image
            ctx.addFieldAction({
                field: field.descriptor,
                label: "AI Image Edit",
                state: "running",
                message: "Generating image...",
            });
        }
    }, 
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [field.descriptor]);
    // Load field buttons when component mounts
    useEffect(() => {
        const loadButtons = async () => {
            if (field.descriptor) {
                try {
                    const buttons = await loadFieldButtons(field.descriptor);
                    setFieldButtons(buttons);
                }
                catch (error) {
                    console.warn("Failed to load field buttons:", error);
                }
            }
        };
        loadButtons();
    }, [field.descriptor]);
    // Load variant buttons from configuration
    useEffect(() => {
        const fieldTypeConfig = editContext?.configuration?.fieldTypes?.picture;
        if (fieldTypeConfig?.variantButtons) {
            setVariantButtons(fieldTypeConfig.variantButtons);
        }
    }, [editContext?.configuration]);
    // Field action handlers
    const handleActionClick = useCallback(async (action, event) => {
        editContext?.triggerFieldAction(field.descriptor, action, undefined, event);
    }, [editContext, field.descriptor]);
    const handleParameterizedActionExecute = useCallback(async (action, parameters) => {
        editContext?.triggerFieldAction(field.descriptor, action, parameters);
    }, [editContext, field.descriptor]);
    const variant = field.value?.variants?.find((v) => v.name === variantName);
    // Variant button action handler with variant context
    const handleVariantButtonClick = useCallback(async (button, event) => {
        const clientButton = button;
        if (clientButton.clientAction && editContext) {
            await clientButton.clientAction({
                editContext,
                field,
                variantName,
                variantData: variant,
                event,
            });
        }
    }, [editContext, field, variantName, variant]);
    const raw = tryParsePictureRawValue(field.rawValue) ?? { Variants: [] };
    const rawVariant = raw.Variants?.find((x) => x.Name == variantName);
    // Filter visible variant buttons
    const visibleVariantButtons = variantButtons.filter((button) => {
        const clientButton = button;
        if (clientButton.visible) {
            return clientButton.visible({
                field,
                variantName,
                variantData: variant,
                rawVariant,
            });
        }
        return true; // Show by default if no visible function
    });
    // Helper function to render icon
    const renderIcon = (icon, isGenerator) => {
        if (!icon) {
            return isGenerator ? (_jsx(Settings, { strokeWidth: 1, size: 16 })) : (_jsx(Zap, { strokeWidth: 1, size: 16 }));
        }
        if (typeof icon === "string") {
            return _jsx("img", { src: icon, alt: "", className: "h-4 w-4" });
        }
        return icon;
    };
    // Separate primary actions (outside menu) and menu actions
    const primaryActions = visibleVariantButtons
        .filter((button) => button.isPimaryAction)
        .map((button) => ({
        id: button.id,
        label: button.label,
        icon: renderIcon(button.icon, button.isGenerator),
        onClick: (e) => {
            const clientButton = button;
            // Handle component actions (like crop)
            if (clientButton.componentAction === "open-cropper") {
                handleOpenCropper();
                return;
            }
            if (button.parameters && button.parameters.length > 0) {
                fieldActionsOverlay.current?.show(e, button);
            }
            else {
                handleVariantButtonClick(button, e?.nativeEvent);
            }
        },
        parameters: button.parameters,
    }));
    // Check if AI image edit is enabled for this field type
    const aiImageEditEnabled = canUseAi &&
        editContext?.configuration?.fieldTypes?.picture?.aiImageEdit !== false;
    // Build actions for the dropdown menu (only buttons with showInMenu !== false)
    const menuActions = [
        // AI Image Edit action (if enabled)
        ...(aiImageEditEnabled
            ? [
                {
                    id: "ai-image-edit",
                    label: "AI Edit",
                    icon: _jsx(Sparkles, { strokeWidth: 1, size: 16 }),
                    onClick: () => handleOpenAiImageEditor(),
                },
            ]
            : []),
        // Variant buttons that should appear in menu
        ...visibleVariantButtons.map((button) => ({
            id: button.id,
            label: button.label,
            icon: renderIcon(button.icon, button.isGenerator),
            onClick: (e) => {
                const clientButton = button;
                // Handle component actions (like crop)
                if (clientButton.componentAction === "open-cropper") {
                    handleOpenCropper();
                    return;
                }
                if (button.parameters && button.parameters.length > 0) {
                    fieldActionsOverlay.current?.show(e, button);
                }
                else {
                    handleVariantButtonClick(button, e?.nativeEvent);
                }
            },
            parameters: button.parameters,
        })),
        // Field-level buttons from server
        ...fieldButtons.map((button) => ({
            id: button.id,
            label: button.label,
            icon: renderIcon(button.icon, button.isGenerator),
            onClick: (e) => {
                if (button.parameters && button.parameters.length > 0) {
                    fieldActionsOverlay.current?.show(e, button);
                }
                else {
                    handleActionClick(button, e?.nativeEvent);
                }
            },
            parameters: button.parameters,
        })),
    ];
    return (_jsxs("div", { className: "absolute inset-0 flex items-center justify-center", onMouseDown: (e) => {
            // Use mouseDown instead of click to fire at the same time as the iframe's mousedown handler
            // This ensures proper selection coordination
            const itemId = field.descriptor.item?.id;
            if (itemId) {
                editContext?.select([itemId]);
            }
            // Stop propagation to prevent the iframe from also trying to handle this
            e.stopPropagation();
        }, onContextMenu: onContextMenu, onWheel: (e) => {
            if (forwardScrollevents)
                editorIframe?.contentWindow?.document.documentElement?.scrollBy({
                    behavior: "instant",
                    left: 0,
                    top: e.deltaY,
                });
            editorIframe?.contentWindow?.document.body?.scrollBy({
                behavior: "instant",
                left: 0,
                top: e.deltaY,
            });
        }, style: style, "data-testid": "select-media", children: [(primaryActions.length > 0 || menuActions.length > 0) && (_jsxs("div", { className: "text-dark border-gray-3 absolute right-2 bottom-2 flex cursor-pointer items-center justify-center overflow-hidden rounded border bg-white text-xs font-medium opacity-70 shadow-lg transition-opacity hover:opacity-85", onClick: (e) => {
                    e.stopPropagation();
                }, children: [primaryActions.map((action, index) => (_jsx("button", { type: "button", className: `hover:bg-gray-5 cursor-pointer px-2 py-1.5 ${index > 0 ? "border-gray-3 border-l" : ""}`, onClick: (e) => {
                            e.stopPropagation();
                            action.onClick(e);
                        }, "data-testid": `primary-action-${action.id}`, children: action.icon }, action.id))), menuActions.length > 0 && (_jsx(ImageEditButton, { actions: menuActions, compact: true, defaultActionId: "select", onOpenChange: setIsMenuOpen, triggerButton: _jsxs("button", { type: "button", className: `hover:bg-gray-5 flex cursor-pointer items-center gap-2 px-2 py-1.5 ${primaryActions.length > 0 ? "border-gray-3 border-l" : ""}`, "data-testid": "menu-toggle-button", children: [_jsx(MagicEditImageIcon, { className: "mr-1" }), " Edit"] }) }))] })), showCropper && (_jsx(PictureCropper, { field: field, onClose: () => setShowCropper(false), variantName: variantName })), _jsx(FieldActionsOverlay, { ref: fieldActionsOverlay, generatorButtons: fieldButtons, onActionClick: handleActionClick, onParameterizedActionExecute: handleParameterizedActionExecute, currentOverlay: editContext?.currentOverlay, fieldId: field.id, setCurrentOverlay: editContext?.setCurrentOverlay || (() => { }), hideBackButton: true, iframe: editorIframe, onOpenChange: setIsOverlayOpen }), canUseAi && showAiImageEditor && (_jsx(AiImageEditorDialog, { open: showAiImageEditor, onClose: () => {
                    setShowAiImageEditor(false);
                    setAiEditOriginalRawValue(null);
                }, onComplete: handleAiEditComplete, fieldDescriptor: field.descriptor, originalRawValue: aiEditOriginalRawValue || "", variantName: variantName, currentImageSrc: variant?.originalSrc || variant?.src, currentMediaItemId: variant?.mediaId }))] }));
}
//# sourceMappingURL=PictureEditor.js.map