import $i18n from '../../../../../../locales/i18n.js';
import React, { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import classNames from 'classnames';
import { CnButton, CnPopup, CnIcon, CnMessage } from '@cainiaofe/cn-ui';
import { DndContext, closestCenter, MouseSensor, TouchSensor, useSensor, useSensors, DragOverlay, } from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { useModel } from '../../../../../../utils/mobx-react-simpler/index.js';
import { cnPopupFloatingLayerOverlayProps, getPopupContainer } from '../../../../../../utils/floating-layer.js';
import { ToolbarDivider } from '../toolbar-divider';
import { useAiTableIcons } from '../../../../../../cn-ai-table/view/hooks/use-ai-table-icons';
import { SortableConditionItem, ConditionItemBody } from './sortable-condition-item';
/** Portal DragOverlay 到 body，避免被父级 filter/overflow/transform 等形成的包含块截断 */
function PortaledDragOverlay({ children, ...props }) {
    return createPortal(React.createElement(DragOverlay, { ...props }, children), document.body);
}
/**
 * 条件设置面板公共组件
 * 用于筛选、排序、分组、填色等条件设置场景。
 *
 * 拖拽排序基于 @dnd-kit 实现：
 * - MouseSensor / TouchSensor 均设 distance: 5 激活阈值，防止点击误触
 * - 仅把手区域（drag-handle）响应拖拽，不干扰内部下拉框、输入框等控件
 * - DragOverlay 提供拖拽中的浮层预览
 */
export function ConditionPanel(props) {
    const { trigger, title, conditions, addButtonText, onAdd, onRemove, onReorder, renderConditionItem, keepVisible = false, maxConditions, placement = 'bl', offset = [0, 10], viewId, currentPageHintText, showAndBeforeCondition = false, showDivider = true, visible: controlledVisible, onVisibleChange: onVisibleChangeProp, shouldOpen, getItemId, popupClassName, } = props;
    // ─── 面板可见性状态（支持受控 & 非受控） ───
    const [internalVisible, setInternalVisible] = useState(false);
    const isControlled = controlledVisible !== undefined && onVisibleChangeProp !== undefined;
    const visible = isControlled ? controlledVisible : internalVisible;
    const setVisible = isControlled ? onVisibleChangeProp : setInternalVisible;
    const icons = useAiTableIcons();
    const keepVisibleRef = useRef(keepVisible);
    keepVisibleRef.current = keepVisible;
    const deferCloseRef = useRef(null);
    const dataModel = useModel('dataModel');
    // ─── dnd-kit 拖拽配置 ───
    const [activeId, setActiveId] = useState(null);
    const sensors = useSensors(useSensor(MouseSensor, { activationConstraint: { distance: 5 } }), useSensor(TouchSensor, { activationConstraint: { distance: 5 } }));
    // 由 conditions 派生 ID:优先用调用方提供的稳定 id,fallback 到 index。
    // fallback 仅适用于不启用拖拽的场景(filter/group/color-fill);启用拖拽时
    // 调用方应实现 getItemId,否则中间项删除/重排会触发子组件重新挂载。
    const sortableIds = React.useMemo(() => conditions.map((c, i) => (getItemId ? getItemId(c, i) : String(i))), [conditions, getItemId]);
    // ─── 面板可见性副作用 ───
    // keepVisible 变化时同步面板状态（通知栏场景：保存/取消后关闭）
    useEffect(() => {
        if (keepVisible) {
            setVisible(true);
        }
        else {
            setVisible(false);
        }
    }, [keepVisible]);
    // 视图切换时关闭面板
    React.useEffect(() => {
        if (viewId && dataModel.activeViewId !== viewId) {
            setVisible(false);
        }
    }, [dataModel.activeViewId, viewId]);
    // 视图选择器打开时关闭面板
    React.useEffect(() => {
        if (!visible)
            return;
        const checkViewTypeSelector = () => {
            const viewTypeSelector = document.querySelector('.view-type-selector');
            if (viewTypeSelector === null || viewTypeSelector === void 0 ? void 0 : viewTypeSelector.offsetParent) {
                setVisible(false);
            }
        };
        const intervalId = setInterval(checkViewTypeSelector, 100);
        return () => clearInterval(intervalId);
    }, [visible]);
    const handleVisibleChange = (newVisible) => {
        if (newVisible) {
            if (deferCloseRef.current) {
                clearTimeout(deferCloseRef.current);
                deferCloseRef.current = null;
            }
            if (shouldOpen && !shouldOpen()) {
                CnMessage.warning($i18n.get({
                    id: 'PleaseConfigureDataInTheFieldMap_1368328697',
                    dm: '请先在编辑态的字段映射中配置数据',
                }));
                return;
            }
            setVisible(true);
            return;
        }
        if (keepVisible) {
            return;
        }
        // portaled 下拉关闭时 CnPopup 先触发 false，子 onChange 稍后才将 keepVisible 置 true。
        // 延迟一个 tick 再判定，避免与 keepVisible effect 打架产生闪烁。
        if (deferCloseRef.current) {
            clearTimeout(deferCloseRef.current);
        }
        deferCloseRef.current = setTimeout(() => {
            deferCloseRef.current = null;
            if (!keepVisibleRef.current) {
                setVisible(false);
            }
        }, 0);
    };
    // 点击外部区域关闭面板（排除：面板自身、通知栏、下拉选择框、trigger 按钮等受保护区域）
    React.useEffect(() => {
        if (!visible)
            return;
        const handleClickOutside = (event) => {
            const target = event.target;
            const tabItem = target.closest('[class*="cn-tab-item"]');
            const addViewButton = tabItem === null || tabItem === void 0 ? void 0 : tabItem.querySelector('[class*="add"]');
            const viewTypeSelector = document.querySelector('.view-type-selector');
            if ((addViewButton && tabItem) || (viewTypeSelector === null || viewTypeSelector === void 0 ? void 0 : viewTypeSelector.offsetParent)) {
                if (!keepVisible) {
                    setVisible(false);
                }
                return;
            }
            if (target.closest('.condition-popup') ||
                target.closest('[class*="cn-popup"]') ||
                target.closest('.date-filter-popup-wrapper') ||
                target.closest('.date-filter-popup') ||
                target.closest('[class*="toolbar-btn"]') ||
                target.closest('[class*="toolbar-notification"]') ||
                target.closest('[class*="cn-select-dropdown"]') ||
                // CnAsyncSelect 等使用 cn-next Menu，选项节点为 cn-next-menu-item-text，不在 cn-select-dropdown 下
                target.closest('[class*="cn-next-menu"]') ||
                target.closest('.field-select-popup')) {
                return;
            }
            if (!keepVisible) {
                setVisible(false);
            }
        };
        // 延迟绑定，避免本次点击立即触发关闭
        const timer = setTimeout(() => {
            document.addEventListener('mousedown', handleClickOutside, true);
        }, 100);
        return () => {
            clearTimeout(timer);
            document.removeEventListener('mousedown', handleClickOutside, true);
        };
    }, [visible, keepVisible]);
    // ─── 业务回调 ───
    const handleAdd = () => {
        if (maxConditions && conditions.length >= maxConditions) {
            return;
        }
        onAdd();
    };
    // ─── 拖拽回调 ───
    const handleDragStart = (event) => {
        setActiveId(event.active.id);
    };
    const handleDragEnd = (event) => {
        const { active, over } = event;
        setActiveId(null);
        if (!over || active.id === over.id || !onReorder)
            return;
        const fromIndex = sortableIds.indexOf(active.id);
        const toIndex = sortableIds.indexOf(over.id);
        if (fromIndex !== -1 && toIndex !== -1) {
            onReorder(fromIndex, toIndex);
        }
    };
    // 浮层渲染期需要根据 activeId 找到对应 condition 与 index
    const activeIndex = activeId !== null ? sortableIds.indexOf(activeId) : -1;
    // ─── 渲染 ───
    const canAdd = maxConditions ? conditions.length < maxConditions : true;
    return (React.createElement(React.Fragment, null,
        React.createElement(CnPopup, { triggerType: "click", visible: visible, onVisibleChange: handleVisibleChange, trigger: trigger, placement: placement, offset: offset, container: getPopupContainer, ...cnPopupFloatingLayerOverlayProps },
            React.createElement("div", { className: classNames('condition-popup', popupClassName) },
                React.createElement("div", { className: "condition-header" },
                    React.createElement("span", null, title),
                    currentPageHintText && (React.createElement("div", { className: "condition-hint-message" },
                        React.createElement(CnIcon, { type: "help-fill", size: "small", className: "hint-icon" }),
                        React.createElement("span", { className: "hint-text" },
                            React.createElement("span", { className: "hint-text-bold" }, $i18n.get({ id: 'PleaseNote', dm: '请注意：' })),
                            currentPageHintText,
                            $i18n.get({ id: 'IsEffectiveByPageDimension', dm: '是按页维度生效的' }))))),
                React.createElement("div", { className: "condition-divider" }),
                React.createElement("div", { className: "condition-content" },
                    React.createElement(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: handleDragStart, onDragEnd: handleDragEnd },
                        React.createElement(SortableContext, { items: sortableIds, strategy: verticalListSortingStrategy }, conditions.map((condition, index) => (React.createElement(SortableConditionItem, { key: sortableIds[index], id: sortableIds[index], index: index, condition: condition, conditions: conditions, showAndBeforeCondition: showAndBeforeCondition, onRemove: onRemove, renderConditionItem: renderConditionItem, dragEnabled: !!onReorder })))),
                        React.createElement(PortaledDragOverlay, null, activeIndex >= 0 ? (React.createElement("div", { className: "condition-item condition-item-drag-overlay" },
                            React.createElement(ConditionItemBody, { index: activeIndex, condition: conditions[activeIndex], conditions: conditions, showAndBeforeCondition: showAndBeforeCondition, onRemove: onRemove, renderConditionItem: renderConditionItem, dragEnabled: !!onReorder }))) : null)),
                    canAdd && (React.createElement("div", { className: "add-condition-container" },
                        React.createElement(CnButton, { text: true, onClick: handleAdd, className: "add-condition-btn" },
                            React.createElement("img", { src: icons.CONDITION_ADD, alt: $i18n.get({ id: 'Add', dm: '添加' }) }),
                            addButtonText)))))),
        showDivider && React.createElement(ToolbarDivider, null)));
}
