import {useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import {closestCenter, DndContext, PointerSensor, useSensor, useSensors} from "@dnd-kit/core";
import {arrayMove, SortableContext, verticalListSortingStrategy} from "@dnd-kit/sortable";
import Widget from "./_components/widget/index";
import Container from "../../../../containers/content/container";
import Empty from "../../../../containers/content/empty";
import TabSettings from "../../../../../components/tab-settings";
import AddWidgetItem from "../../../../../../popups/widgets/add-widget-item";
import {GROUP_ITEMS_DATA} from "./_data";

// Constants
const TAB_NAME = 'settings.chatbot.widgets';

export default function Widgets({notifications, setChatbotPreview}) {
    // Actions states
    const [saving, setSaving] = useState(false);
    const [newWidgetItemsIds, setNewWidgetItemsIds] = useState([]);
    const [showAddWidgetPopup, setShowAddWidgetPopup] = useState(false);
    const [prependWidget, setPrependWidget] = useState(false);
    // Settings
    const settings = {
        'widgets': useState([]),
    };
    // Dnd context
    const sensors = useSensors(useSensor(PointerSensor));

    /**
     * Handle widget type selection from popup
     * @param {string} type Widget type
     */
    const handleWidgetTypeSelect = (type) => {
        const id = Math.random().toString(36).substring(2, 12);
        const itemData = GROUP_ITEMS_DATA[type] ? JSON.parse(JSON.stringify(GROUP_ITEMS_DATA[type])) : JSON.parse(JSON.stringify(GROUP_ITEMS_DATA['prompt']));

        // Determine default location based on type
        const defaultLocation = (type === 'message' || type === 'lead_capture') ? 'new_chat' : 'home';

        const newItem = {
            id,
            type: type,
            published: true,
            data: itemData,
            locations: [[{
                param: 'screen',
                operator: '===',
                value: defaultLocation,
            }]],
            title: ''
        };

        // Message specific settings
        if (type === 'message') {
            newItem.notify = false;
        }

        if (prependWidget) {
            settings['widgets'][1](prevState => [newItem, ...prevState]);
        } else {
            settings['widgets'][1](prevState => [...prevState, newItem]);
        }
        setNewWidgetItemsIds(prevState => [...prevState, id]);
        setShowAddWidgetPopup(false);
    }

    /**
     * Open add widget popup
     * @param {boolean} prepend Whether to add at the beginning (true) or end (false)
     */
    const openAddWidgetPopup = (prepend = false) => {
        setPrependWidget(prepend);
        setShowAddWidgetPopup(true);
    }

    /**
     * Handle DnD end
     *
     * @param event
     */
    const handleDragEnd = (event) => {
        const {active, over} = event;

        if (!over || active.id === over.id) {
            return;
        }

        settings['widgets'][1](prevState => {
            const oldIndex = prevState.findIndex(item => item.id === active.id);
            const newIndex = prevState.findIndex(item => item.id === over.id);

            if (oldIndex === -1 || newIndex === -1) {
                return prevState;
            }

            return arrayMove(prevState, oldIndex, newIndex);
        });
    }

    /**
     * Move item up
     *
     * @param {number} index Item index
     */
    const moveItemUp = (index) => {
        if (index !== 0) {
            settings['widgets'][1](prevState => arrayMove(prevState, index, index - 1));
        }
    }

    /**
     * Move item down
     *
     * @param {number} index Item index
     */
    const moveItemDown = (index) => {
        if (index !== settings['widgets'][0].length - 1) {
            settings['widgets'][1](prevState => arrayMove(prevState, index, index + 1));
        }
    }

    return <>
        <TabSettings
            name={TAB_NAME}
            settings={settings}
            notifications={notifications}
            keysPrefix='lbaic.utilities.chatbot'
            updateSaving={value => setSaving(value)}
            setChatbotPreview={setChatbotPreview}
            shouldUpdatePreviewData
            footerChildren={
                settings['widgets'][0].length > 0 &&
                <button onClick={() => openAddWidgetPopup(false)}
                        className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary lbaic-settings-cb-pw-footer-actions-in lbaic-settings-content-footer-actions-in${saving ? ' lbaic-settings-button-disabled' : ''}`}>
                    <span className='lbaic-settings-button-label'>{__("Add widget", 'limb-chatbot')}</span>
                </button>
            }
        >
            <Container className="lbaic-settings-cb-pw-container">
                {settings['widgets'][0].length > 0 &&
                    <>
                        <div className="lbaic-settings-cb-pw-column">
                            <div className="lbaic-settings-cb-pw-column-in">
                                <div className='lbaic-settings-table-accordion lbaic-settings-cb-pw-table-inside'>
                                    <DndContext sensors={sensors} collisionDetection={closestCenter}
                                                onDragEnd={handleDragEnd}>
                                        <SortableContext items={settings['widgets'][0]}
                                                         strategy={verticalListSortingStrategy}>
                                            {settings['widgets'][0].map((item, i) =>
                                                <Widget
                                                    key={item.id}
                                                    widgetItem={item}
                                                    index={i}
                                                    isLastItem={i === settings['widgets'][0].length - 1}
                                                    moveUp={() => moveItemUp(i)}
                                                    moveDown={() => moveItemDown(i)}
                                                    update={settings['widgets'][1]}
                                                    newWidgetItemsIds={newWidgetItemsIds}
                                                    chatbotUuid="default"
                                                    notifications={notifications}
                                                />
                                            )}
                                        </SortableContext>
                                    </DndContext>
                                </div>
                            </div>
                        </div>
                    </>}
                {!settings['widgets'][0].length &&
                    <div className="lbaic-settings-cb-pw-container-in">
                        <Empty title={__("No prompts & widgets yet", 'limb-chatbot')}
                               subtitle={__("Start by adding your first one", 'limb-chatbot')}
                               icon='tab-pw-active'>
                            <div className='lbaic-settings-empty-actions'>
                                <button onClick={openAddWidgetPopup}
                                        className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary'>
                                    <span className='lbaic-settings-button-label'>{__("Add new", 'limb-chatbot')}</span>
                                </button>
                            </div>
                        </Empty>
                    </div>
                }
            </Container>
        </TabSettings>
        {showAddWidgetPopup &&
            <AddWidgetItem
                close={() => setShowAddWidgetPopup(false)}
                onSelect={handleWidgetTypeSelect}
                location={null}
            />}
    </>
}