import {useEffect, useRef, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import Input from "../../../../../../../fields/input";
import DualInput from "../../../../../../../fields/dual-input";
import Checkbox from "../../../../../../../fields/checkbox";
import {handleError, handleSuccess, handleWarning} from "../../../../../../../../helpers/notifications";
import {required, validate} from "../../../../../../../../../validations";
import BlockEditable from "../../../../../../../fields/blockeditable";
import DatasetEntry from "../dataset-entry";
import {
    CreateDatasetEntry,
    DeleteDatasetEntry,
    GetDatasetEntries,
    GetDatasetEntry,
    UpdateDatasetEntry
} from "../../../../../../../../rest/dataset-entries";
import Pagination from "../../../../../../../sections/pagination";
import RunDataset from "../../../../../../../popups/advanced/training/datasets/run";
import {getUtilityLinkTo} from "../../../../../../../../helpers";
import {CreateDataset, DATASET_TYPE_FINE_TUNING, UpdateDataset} from "../../../../../../../../rest/datasets";
import ContentBodyInner from "../../../../../containers/content/body-inner";
import Container from "../../../../../containers/content/container";
import ContentLoading from "../../../../../containers/content/loading";
import useUnsavedChangesWarning from "../../../../../../components/unsaved-changes-warning";
import ContentFooterLayout from "../../../../../containers/content/footer/_components/layout";
import {areDeepEqual, generateUniqueId} from "../../../../../../../../../helpers";
import Toggle from "../../../../../../../fields/toggle";

export default function AddEdit({data, setData, loading, setLoading, cancel, notifications, navigate}) {
    const [isDataFetched, setIsDataFetched] = useState(false);
    const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
    const [addEntryButtonDisabled, setAddEntryButtonDisabled] = useState(true);
    const [saving, setSaving] = useState(false);
    const [editDatasetEntryId, setEditDatasetEntryId] = useState(null);
    // States
    const [showRunPopup, setShowRunPopup] = useState(false);
    const [allMessagesCount, setAllMessagesCount] = useState(0);
    const [selectedMessages, setSelectedMessages] = useState([]);
    const [pagination, setPagination] = useState({
        page: 1,
        perPage: LimbChatbot.screen_options?.lbaic_items_per_page || 10,
        total: 0,
    });
    // Data
    const [datasetData, setDatasetData] = useState({
        name: '',
        instruction: '',
    });
    const [defineAssistantPersona, setDefineAssistantPersona] = useState(false);
    const [datasetEntries, setDatasetEntries] = useState([]);
    const errors = {
        'name': useState(false),
        'instruction': useState(false),
    };
    const initialData = useRef({
        name: '',
        instruction: '',
    });
    const initialEntriesData = useRef([]);
    const datasetEntriesRefs = useRef([]);
    // New message state
    const [newMessage, setNewMessage] = useState({
        input: '',
        output: '',
    });
    const newMessageErrors = {
        'input': useState(false),
        'output': useState(false)
    };

    useEffect(() => {
        // Detect action
        const searchParams = new URLSearchParams(window.location.search);
        const datasetEntryId = +searchParams.get('dataset_entry_id');
        if (datasetEntryId && !isNaN(datasetEntryId)) {
            setEditDatasetEntryId(datasetEntryId);
        }
    }, []);

    useEffect(() => {
        if (!isDataFetched) {
            fetchData();
        } else {
            // Real initial data sets
            initialData.current = JSON.parse(JSON.stringify(datasetData));
            initialEntriesData.current = JSON.parse(JSON.stringify(datasetEntries));
        }
    }, [isDataFetched, data]);

    useEffect(() => {
        setAllMessagesCount(datasetEntries.reduce((acc, item) => acc + (item.entry?.messages?.length || 0), 0));
    }, [datasetEntries]);

    useEffect(() => {
        setAddEntryButtonDisabled(!newMessage.input.trim() || !newMessage.output.trim());
    }, [newMessage]);

    // Check unsaved changes before leaving the page
    useUnsavedChangesWarning(hasUnsavedChanges);

    /**
     * Check is data changed
     */
    const checkIsDataChanged = () => {
        // Check if data changed
        const dataEqual = areDeepEqual(datasetData, initialData.current);
        const entriesEqual = areDeepEqual(datasetEntries, initialEntriesData.current);
        setHasUnsavedChanges(!dataEqual || !entriesEqual);
    }

    useEffect(() => {
        checkIsDataChanged();
    }, [datasetData, datasetEntries]);

    /**
     * Fetch data
     */
    const fetchData = async () => {
        setLoading(prev => prev + 1);
        setDatasetData({
            name: data?.name || '',
            instruction: data?.instruction || '',
        });
        // Enable the assistant persona toggle if it has been defined
        if (data?.instruction) {
            setDefineAssistantPersona(true);
        }
        // Check dataset entry id
        const searchParams = new URLSearchParams(window.location.search);
        const datasetEntryId = +searchParams.get('dataset_entry_id');
        // Fetch dataset entries
        if (datasetEntryId && !isNaN(datasetEntryId)) {
            await fetchDatasetEntry(datasetEntryId);
        } else {
            await fetchDatasetEntries(pagination.page, pagination.perPage);
        }
        setLoading(prev => prev - 1);
        setIsDataFetched(true);
    }

    /**
     * Fetch dataset entry
     *
     * @param {number} datasetEntryId Dataset entry ID
     * @return {Promise<void>}
     */
    const fetchDatasetEntry = async (datasetEntryId) => {
        setLoading(prev => prev + 1);
        if (datasetEntryId) {
            try {
                const res = await GetDatasetEntry(LimbChatbot.rest.url, LimbChatbot.rest.nonce, datasetEntryId);
                if (res?.id) {
                    setDatasetEntries([res]);
                } else {
                    handleWarning(res, notifications.set, {
                        title: __("Failed to get the Q&A entry.", 'limb-chatbot'),
                        description: __("Something went wrong.", 'limb-chatbot'),
                    });
                }
            } catch (e) {
                handleError(e, notifications.set, {
                    title: __("Failed to get the Q&A entry.", 'limb-chatbot'),
                    description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
                });
            }
        }
        setLoading(prev => prev - 1);
    }

    /**
     * Fetch dataset entries
     *
     * @param {number} page Page
     * @param {number} perPage Per Page
     * @return {Promise<void>}
     */
    const fetchDatasetEntries = async (page, perPage) => {
        setLoading(prev => prev + 1);
        if (data?.id) {
            try {
                const res = await GetDatasetEntries(LimbChatbot.rest.url, LimbChatbot.rest.nonce, data.id, {
                    page: page,
                    per_page: perPage
                });
                if (res.items?.length) {
                    setDatasetEntries([...res.items]);
                }
                // Update pagination
                setPagination(prevState => ({
                    ...prevState,
                    page: page,
                    total: +res.total,
                }));
            } catch (e) {
                handleError(e, notifications.set, {
                    title: __("Failed to get Q&A entries.", 'limb-chatbot'),
                    description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
                });
            }
        } else {
            setDatasetEntries([]);
        }
        setLoading(prev => prev - 1);
    }

    /**
     * Validate field
     *
     * @param {string} name Field name
     * @param {any} value Field value
     * @param {object} errors Errors state
     * @return {boolean}
     */
    const validateField = (name, value, errors) => {
        try {
            let validations = [];

            switch (name) {
                case 'name':
                // case 'instruction':
                case 'input':
                case 'output':
                    validations = [required];
                    break;
                default:
                    break;
            }
            const res = validate(value, validations);
            // Update field errors state
            if (name in errors) {
                errors[name][1](!res.valid ? res.message : false);
            }

            return res.valid;
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Field validation failed.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Something went wrong.", 'limb-chatbot'),
            });
            return false;
        }
    }

    /**
     * Add new dataset entry
     */
    const addNewDatasetEntry = () => {
        // Validate
        let hasError = false;
        for (const item of Object.keys(newMessage)) {
            if (!validateField(item, newMessage[item], newMessageErrors)) {
                hasError = true;
            }
        }
        if (!validateField('instruction', datasetData.instruction, errors)) {
            hasError = true;
        }
        if (!hasError) {
            const newEntry = {
                unique_id: generateUniqueId(),
                entry: {
                    system: datasetData.instruction,
                    messages: [
                        {
                            input: newMessage.input,
                            output: newMessage.output,
                            // weight: 1
                        }
                    ],
                }
            };
            if (data?.id) {
                newEntry.dataset_id = data.id;
            }
            setDatasetEntries(prevState => [
                ...prevState,
                newEntry
            ]);
            // Reset inputs
            setNewMessage(prevState => ({
                ...prevState,
                input: '',
                output: '',
            }));
            return true;
        }
        return false;
    }

    /**
     * Update dataset entry system message
     *
     * @param {string} systemMessage System message
     * @param {number} entryIndex Entry index
     */
    const updateDatasetEntrySystemMessage = (systemMessage, entryIndex) => {
        setDatasetEntries(prevState => prevState.map((item, index) => {
            if (entryIndex === index) {
                return {
                    ...item,
                    entry: {
                        ...item.entry,
                        system: systemMessage
                    },
                }
            }

            return item;
        }));
    }

    /**
     * Add dataset entry message
     *
     * @param {object} messageData Message data
     * @param {number} entryIndex Entry index
     */
    const addDatasetEntryMessage = (messageData, entryIndex) => {
        setDatasetEntries(prevState => prevState.map((item, index) => {
            if (entryIndex !== index) {
                return {
                    ...item,
                    entry: {
                        ...item.entry,
                        messages: [
                            ...item.entry.messages,
                            {
                                input: messageData.input,
                                output: messageData.output,
                            }
                        ],
                    },
                }
            }

            return item;
        }));
    }

    /**
     * Update dataset entry message
     *
     * @param {object} messageData Message data
     * @param {number} messageIndex Message index
     * @param {number} entryIndex Entry index
     */
    const updateDatasetEntryMessage = (messageData, messageIndex, entryIndex) => {
        setDatasetEntries(prevState => prevState.map((item, index) => {
            if (entryIndex === index) {
                return {
                    ...item,
                    entry: {
                        ...item.entry,
                        messages: item.entry.messages.map((item2, index2) => {
                            if (messageIndex !== index2) {
                                return item2;
                            }
                            return {
                                ...item2,
                                ...messageData,
                            };
                        })
                    },
                }
            }

            return item;
        }));
    }

    /**
     * Delete selected messages
     */
    const deleteSelectedMessages = () => {
        if (selectedMessages?.length) {
            setDatasetEntries(prevState => prevState.map((item, datasetIndex) => ({
                ...item,
                entry: {
                    ...item.entry,
                    messages: item.entry.messages.filter((message, messageIndex) => selectedMessages.indexOf(`${datasetIndex}.${messageIndex}`) === -1)
                },
            })));
            setSelectedMessages([]);
        }
    }

    /**
     * Toggle run popup
     *
     * @param {boolean} autoClose After run request close the edit screen also
     */
    const toggleRunPopup = (autoClose = false) => {
        if (showRunPopup) {
            if (autoClose === true) {
                cancel();
                navigate(getUtilityLinkTo('training', 'my-models'));
            }
        }
        setShowRunPopup(!showRunPopup);
    }

    /**
     * Validate data to save
     *
     * @return {boolean}
     */
    const validateDataToSave = () => {
        // Validate
        let hasError = false;
        for (const item of Object.keys(datasetData)) {
            if (!validateField(item, datasetData[item], errors)) {
                hasError = true;
            }
        }
        return !hasError;
    }

    /**
     * Save dataset
     */
    const save = async () => {
        if (!validateDataToSave()) {
            // Errors are already shown
            return;
        }
        setSaving(true);
        if (!data?.id) {
            CreateDataset(LimbChatbot.rest.url, LimbChatbot.rest.nonce, {
                name: datasetData.name,
                instruction: datasetData.instruction,
                type: DATASET_TYPE_FINE_TUNING,
            }).then(async res => {
                if (res.dataset?.id) {
                    setData(res.dataset);
                } else {
                    setSaving(false);
                    handleError(false, notifications.set, {
                        title: __("Failed to save Q&A.", 'limb-chatbot'),
                        description: __("Something went wrong.", 'limb-chatbot'),
                    });
                    return;
                }
                // Save dataset entries
                const saveEntriesState = {
                    tried: [],
                    saved: [],
                    failed: [],
                    errors: [],
                };
                for (const i in datasetEntries) {
                    // Check messages
                    if (!datasetEntries[i].entry.messages?.length) {
                        continue;
                    }
                    // Create dataset entry
                    try {
                        saveEntriesState.tried.push({
                            index: +i
                        });
                        const datasetEntryRes = await CreateDatasetEntry(LimbChatbot.rest.url, LimbChatbot.rest.nonce, res.dataset.id, {
                            dataset_id: res.dataset.id,
                            entry: datasetEntries[i].entry,
                        });
                        // Update dataset entry state
                        if (datasetEntryRes?.id) {
                            saveEntriesState.saved.push({
                                index: +i,
                                data: datasetEntryRes,
                            });
                        } else {
                            saveEntriesState.failed.push({
                                index: +i,
                            });
                        }
                    } catch (e) {
                        handleError(e);
                        saveEntriesState.failed.push({
                            index: +i,
                        });
                        if (e.message && saveEntriesState.errors.indexOf(e.message) === -1) {
                            saveEntriesState.errors.push(e.message);
                        }
                    }
                }
                // Sync data
                if (saveEntriesState.saved.length > 0) {
                    // State
                    setDatasetEntries(datasetEntries.map((item, i) => {
                        const savedEntry = saveEntriesState.saved.find(savedItem => savedItem.index === i);
                        if (savedEntry) {
                            return savedEntry.data;
                        }
                        return item;
                    }));
                    // Initial data
                    for (const savedItem of saveEntriesState.saved) {
                        initialEntriesData.current[savedItem.index] = JSON.parse(JSON.stringify(savedItem.data));
                    }
                }
                setSaving(false);
                if (saveEntriesState.failed.length > 0) {
                    handleError(false, notifications.set, {
                        title: saveEntriesState.tried.length === saveEntriesState.failed.length ? __("Failed to save entries.", 'limb-chatbot') : __("Failed to save some entries.", 'limb-chatbot'),
                        description: saveEntriesState.errors.length ? saveEntriesState.errors.map(message => __(message, 'limb-chatbot')).join(' ') : __("Something went wrong.", 'limb-chatbot'),
                    });
                } else {
                    handleSuccess(notifications.set, {
                        title: __("Data saved successfully.", 'limb-chatbot'),
                    });
                }
            }).catch(e => {
                setSaving(false);
                handleError(e, notifications.set, {
                    title: __("Failed to save data.", 'limb-chatbot'),
                    description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
                });
            });
        } else {
            const requests = {
                tried: false,
                success: true,
            };
            // Update dataset
            if (!areDeepEqual(datasetData, initialData.current)) {
                try {
                    requests.tried = true;
                    const res = await UpdateDataset(LimbChatbot.rest.url, LimbChatbot.rest.nonce, data.id, {
                        name: datasetData.name,
                        instruction: datasetData.instruction,
                    });
                    if (res.dataset?.id) {
                        setData(res.dataset);
                        initialData.current = JSON.parse(JSON.stringify(datasetData));
                    }
                } catch (e) {
                    requests.success = false;
                    handleError(e, notifications.set, {
                        title: __("Failed to save data.", 'limb-chatbot'),
                        description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
                    });
                }
            }
            // Update dataset entries
            const saveEntriesState = {
                tried: [],
                saved: [],
                deleted: [],
                failed: [],
                errors: [],
            };
            for (const i in datasetEntries) {
                if (typeof datasetEntriesRefs.current[i]?.wasChanged === 'function') {
                    if (!datasetEntriesRefs.current[i].wasChanged()) {
                        continue;
                    }
                }
                // Check messages
                if (!datasetEntries[i].entry.messages?.length) {
                    if (datasetEntries[i].id) {
                        // Delete dataset entry
                        try {
                            requests.tried = true;
                            saveEntriesState.tried.push({
                                index: +i,
                            });
                            await DeleteDatasetEntry(LimbChatbot.rest.url, LimbChatbot.rest.nonce, datasetEntries[i].id);
                            // Keep delete info
                            saveEntriesState.deleted.push(datasetEntries[i].id);
                        } catch (e) {
                            handleError(e);
                            requests.success = false;
                            // Entries error messages
                            saveEntriesState.failed.push({
                                index: +i,
                            });
                            if (e.message && saveEntriesState.errors.indexOf(e.message) === -1) {
                                saveEntriesState.errors.push(e.message);
                            }
                        }
                    }
                    continue;
                }
                // Save dataset entry
                try {
                    requests.tried = true;
                    saveEntriesState.tried.push({
                        index: +i,
                    });
                    const datasetEntryRes = datasetEntries[i].id ?
                        await UpdateDatasetEntry(LimbChatbot.rest.url, LimbChatbot.rest.nonce, datasetEntries[i].id, {
                            entry: datasetEntries[i].entry
                        })
                        :
                        await CreateDatasetEntry(LimbChatbot.rest.url, LimbChatbot.rest.nonce, datasetEntries[i].dataset_id, {
                            dataset_id: datasetEntries[i].dataset_id,
                            entry: datasetEntries[i].entry,
                        });
                    // Keep update info
                    if (datasetEntryRes?.id) {
                        saveEntriesState.saved.push({
                            index: +i,
                            data: {
                                ...datasetEntryRes,
                                dataset_id: datasetEntries[i].dataset_id, // Because it not comes in the response
                            },
                        });
                    } else {
                        saveEntriesState.failed.push({
                            index: +i,
                        });
                    }
                } catch (e) {
                    handleError(e);
                    requests.success = false;
                    // Entries error messages
                    saveEntriesState.failed.push({
                        index: +i,
                    });
                    if (e.message && saveEntriesState.errors.indexOf(e.message) === -1) {
                        saveEntriesState.errors.push(e.message);
                    }
                }
            }
            setSaving(false);
            if (requests.tried) {
                if (requests.success) {
                    handleSuccess(notifications.set, {
                        title: __("Data saved successfully.", 'limb-chatbot'),
                    });
                } else {
                    // Show entries save error messages
                    if (saveEntriesState.failed.length > 0) {
                        handleError(false, notifications.set, {
                            title: saveEntriesState.tried.length === saveEntriesState.failed.length ? __("Failed to save entries.", 'limb-chatbot') : __("Failed to save some entries.", 'limb-chatbot'),
                            description: saveEntriesState.errors.length > 0 ? saveEntriesState.errors.map(message => __(message, 'limb-chatbot')).join(' ') : __("Something went wrong.", 'limb-chatbot'),
                        });
                    }
                }
            } else {
                handleWarning(false, notifications.set, {
                    title: __("Attention", 'limb-chatbot'),
                    description: __("There is no changes to save.", 'limb-chatbot'),
                });
            }
            // Update state
            const entriesUpdatedState = JSON.parse(JSON.stringify(datasetEntries));
            // Created/updated entries
            if (saveEntriesState.saved.length > 0) {
                for (const updatedEntry of saveEntriesState.saved) {
                    // State
                    entriesUpdatedState[updatedEntry.index] = updatedEntry.data;
                    // Initial
                    initialEntriesData.current[updatedEntry.index] = JSON.parse(JSON.stringify(updatedEntry.data));
                }
            }
            // Deleted entries
            if (saveEntriesState.deleted.length > 0) {
                for (const deletedEntryId of saveEntriesState.deleted) {
                    // State
                    const i = entriesUpdatedState.findIndex(item => item.id === deletedEntryId);
                    if (i !== -1) {
                        entriesUpdatedState.splice(i, 1);
                    }
                    // Initial
                    const j = initialEntriesData.current.findIndex(item => item.id === deletedEntryId);
                    if (j !== -1) {
                        initialEntriesData.current.splice(j, 1);
                    }
                }
            }
            setDatasetEntries([...entriesUpdatedState]);
        }
    }

    return <>
        <ContentBodyInner>
            {loading > 0 && !isDataFetched && <ContentLoading/>}
            <Container className="lbaic-settings-a-ftds">
                <div className='lbaic-settings-a-ftds-body'>
                    {!!data?.id &&
                        <div className='lbaic-settings-column'>
                            <div className='lbaic-settings-column-in'>
                                <div className='lbaic-settings-a-ftds-id'>
                                        <span
                                            className='lbaic-settings-a-ftds-id-label'>{__("Q&A ID", 'limb-chatbot')}: {data.id}</span>
                                </div>
                            </div>
                        </div>}
                    <div className='lbaic-settings-column'>
                        <div className='lbaic-settings-column-in'>
                            <Input value={datasetData.name}
                                   setValue={(value) => setDatasetData(prevState => ({...prevState, name: value}))}
                                   placeholder={__("Name", 'limb-chatbot')}
                                   autofocus
                                   validate={(value) => validateField('name', value, errors)}
                                   errorMessage={errors['name'][0]}/>
                        </div>
                        <div className='lbaic-settings-column-in'>
                            <Toggle label={__("Training mode", 'limb-chatbot')}
                                    isActive={defineAssistantPersona}
                                    onClick={() => setDefineAssistantPersona(prevState => !prevState)}/>
                        </div>
                    </div>
                    {defineAssistantPersona &&
                        <BlockEditable value={datasetData.instruction}
                                       setValue={(value) => setDatasetData(prevState => ({
                                           ...prevState,
                                           instruction: value
                                       }))}
                                       label={__("Assistant Persona", 'limb-chatbot')}
                                       validate={(value) => validateField('instruction', value, errors)}
                                       errorMessage={errors['instruction'][0]} notifications={notifications}/>}
                    <div className={`lbaic-settings-divider${defineAssistantPersona ? ' lbaic-settings-divider-gap' : ' lbaic-settings-divider-gap-end'}`}/>
                    <div className='lbaic-settings-column'>
                        <div className='lbaic-settings-column-in'>
                            <div className='lbaic-settings-a-ftds-input'>
                                <DualInput className='lbaic-settings-dual-input-has-children'
                                           value1={newMessage.input}
                                           setValue1={(value) => setNewMessage(prevState => ({
                                               ...prevState,
                                               input: value
                                           }))}
                                           placeholder1={__("Question", 'limb-chatbot')}
                                           validate1={(value) => validateField('input', value, newMessageErrors)}
                                           errorMessage1={newMessageErrors['input'][0]}
                                           value2={newMessage.output}
                                           setValue2={(value) => setNewMessage(prevState => ({
                                               ...prevState,
                                               output: value
                                           }))}
                                           placeholder2={__("Answer", 'limb-chatbot')}
                                           validate2={(value) => validateField('output', value, newMessageErrors)}
                                           errorMessage2={newMessageErrors['output'][0]}
                                           save={addNewDatasetEntry}
                                           notifications={notifications}
                                           holderClassName='flex'/>
                                <div className='lbaic-settings-a-ftds-input-action'>
                                    <button onClick={addNewDatasetEntry}
                                            className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-34 lbaic-settings-button-minimal${addEntryButtonDisabled ? ' lbaic-settings-button-disabled' : ''}`}>
                                        <span className='lbaic-settings-button-label'>{__("Add entry", 'limb-chatbot')}</span>
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className='lbaic-settings-scroll-hidden'>
                        <div className='lbaic-settings-a-ftds-table-wrapper lbaic-settings-scroll-x lbaic-settings-scroll-style'>
                            <table className='lbaic-settings-a-ftds-table'>
                                <thead className='lbaic-settings-a-ftds-table-header'>
                                <tr className='lbaic-settings-a-ftds-table-header-in'>
                                    <th className='lbaic-settings-a-ftds-table-header-item lbaic-settings-a-ftds-table-checkbox'>
                                        <Checkbox
                                            isChecked={allMessagesCount && selectedMessages.length === allMessagesCount}
                                            toggleValue={() => {
                                                if (allMessagesCount) {
                                                    if (selectedMessages.length === allMessagesCount) {
                                                        setSelectedMessages([]);
                                                    } else {
                                                        setSelectedMessages([...datasetEntries.reduce((acc, item, i) => acc.concat(item.entry.messages.map((m, j) => `${i}.${j}`)), [])]);
                                                    }
                                                } else {
                                                    setSelectedMessages([]);
                                                }
                                            }}/>
                                    </th>
                                    <th className='lbaic-settings-a-ftds-table-header-item lbaic-settings-a-ftds-table-input'>
                                            <span
                                                className='lbaic-settings-a-ftds-table-header-label'>{__("Question", 'limb-chatbot')}</span>
                                    </th>
                                    <th className='lbaic-settings-a-ftds-table-header-item lbaic-settings-a-ftds-table-output'>
                                        <div className='lbaic-settings-a-ftds-table-flex'>
                                                <span
                                                    className='lbaic-settings-a-ftds-table-header-label'>{__("Answer", 'limb-chatbot')}</span>
                                            <span
                                                className='lbaic-settings-a-ftds-table-header-label'>{selectedMessages.length}/{allMessagesCount} {__("selected", 'limb-chatbot')}</span>
                                        </div>
                                    </th>
                                </tr>
                                </thead>
                                <tbody className='lbaic-settings-a-ftds-table-body'>
                                {datasetEntries.map((item, i) =>
                                    <DatasetEntry key={item.id || item.unique_id}
                                                  ref={(el) => (datasetEntriesRefs.current[i] = el)}
                                                  entry={item} index={i}
                                                  setSystemMessage={updateDatasetEntrySystemMessage}
                                                  addMessage={addDatasetEntryMessage}
                                                  updateMessage={updateDatasetEntryMessage}
                                                  selected={selectedMessages} setSelected={setSelectedMessages}
                                                  defineAssistantPersona={defineAssistantPersona}
                                                  autofocus={editDatasetEntryId === item.id}
                                                  notifications={notifications}/>)}
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                {data?.id &&
                    <Pagination page={pagination.page} perPage={pagination.perPage} total={pagination.total}
                                goTo={(page) => fetchDatasetEntries(page, pagination.perPage)}/>}
            </Container>
        </ContentBodyInner>
        <ContentFooterLayout loading={!!loading || saving}>
            <button onClick={() => (!loading && !saving && hasUnsavedChanges) && save()}
                    className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary${loading || saving || !hasUnsavedChanges ? ' lbaic-settings-button-disabled' : ''}`}>
                <span className='lbaic-settings-button-label'>{__("Save changes", 'limb-chatbot')}</span>
            </button>
            <button onClick={cancel}
                    className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-secondary lbaic-settings-content-footer-actions-end'>
                <span className='lbaic-settings-button-label'>{__("Cancel", 'limb-chatbot')}</span>
            </button>
            {selectedMessages.length > 0 &&
                <button onClick={deleteSelectedMessages}
                        className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-danger${!selectedMessages.length || loading || saving ? ' lbaic-settings-button-disabled' : ''}`}>
                    <svg className='lbaic-settings-button-i' xmlns='http://www.w3.org/2000/svg' fill='none'
                         viewBox='0 0 24 24'>
                        <use href='#lbaic-settings-delete'/>
                    </svg>
                    <span className='lbaic-settings-button-label'>{__("Delete", 'limb-chatbot')}</span>
                </button>}
            {defineAssistantPersona && !editDatasetEntryId &&
                <button onClick={toggleRunPopup}
                        className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary${!data?.id ? ' lbaic-settings-button-disabled' : ''}`}>
                    <svg className='lbaic-settings-button-i' xmlns='http://www.w3.org/2000/svg' fill='none'
                         viewBox='0 0 24 24'>
                        <use href='#lbaic-settings-run'/>
                    </svg>
                    <span className='lbaic-settings-button-label'>{__("Run", 'limb-chatbot')}</span>
                </button>}
        </ContentFooterLayout>
        {showRunPopup &&
            <RunDataset datasetId={data?.id} close={toggleRunPopup} notifications={notifications}/>}
    </>
}