import {forwardRef, useEffect, useImperativeHandle, useRef, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import Checkbox from "../../../../../../../fields/checkbox";
import Copilot from "../../../../../../../button/copilot";
import AddEditMessage from "./message/add-edit";
import {areDeepEqual} from "../../../../../../../../../helpers";

const DatasetEntry = forwardRef(({entry, index, setSystemMessage, addMessage, updateMessage, selected, setSelected, defineAssistantPersona, autofocus, notifications}, ref) => {
    const [showSubMessages, setShowSubMessages] = useState(false);
    const [showSystemMessage, setShowSystemMessage] = useState(false);
    const [changed, setChanged] = useState(false);
    // Data
    const [defaultSystemMessage, setDefaultSystemMessage] = useState(entry.entry.system || '');
    const [editMessage, setEditMessage] = useState(null);
    // Initial data
    const initialData = useRef(entry);

    useImperativeHandle(ref, () => ({
        wasChanged() {
            return changed || !entry.id;
        },
    }));

    useEffect(() => {
        if (autofocus) {
            setEditMessage(prevState => ({
                data: {
                    ...entry.entry.messages[0],
                },
                index: 0,
                autofocus: 1,
            }));
        }
    }, [autofocus]);

    useEffect(() => {
        const deepEqual = areDeepEqual(initialData.current, entry);
        setChanged(!deepEqual);
    }, [entry]);

    /**
     * Save message
     *
     * @param {object} messageData Message
     * @param {number} messageIndex Message index
     */
    const saveMessage = (messageData, messageIndex) => {
        updateMessage(messageData, messageIndex, index);
        setEditMessage(null);
    }

    /**
     * Render sub message
     *
     * @param {object} message Message data
     * @param {number} messageIndex Message index
     * @return {JSX.Element|boolean}
     */
    const renderSubMessage = (message, messageIndex) => {
        if (messageIndex === 0) {
            return false;
        }
        return <>
            {messageIndex === editMessage?.index ?
                <AddEditMessage message={editMessage.data} buttonLabel={__("Save", 'limb-chatbot')}
                                autofocusOn={editMessage.autofocus}
                                save={(data) => saveMessage(data, messageIndex)} cancel={() => setEditMessage(null)}
                                notifications={notifications}/>
                :
                <tr key={messageIndex} className='lbaic-settings-a-ftds-table-nested-body-in lbaic-settings-a-ftds-table-nested-body-border'>
                    <td className='lbaic-settings-a-ftds-table-nested-body-item lbaic-settings-a-ftds-table-checkbox'>
                        <Checkbox isChecked={selected.indexOf(`${index}.${messageIndex}`) !== -1} toggleValue={() => {
                            const i = selected.indexOf(`${index}.${messageIndex}`);
                            if (i === -1) {
                                setSelected(prevState => [...prevState, `${index}.${messageIndex}`]);
                            } else {
                                setSelected(prevState => prevState.filter(item => item !== `${index}.${messageIndex}`));
                            }
                        }}/>
                    </td>
                    <td className='lbaic-settings-a-ftds-table-nested-body-item lbaic-settings-a-ftds-table-input'>
                        <span className='lbaic-settings-a-ftds-table-nested-body-label'
                              onDoubleClick={() => setEditMessage(prevState => ({
                                  data: {
                                      ...message,
                                  },
                                  index: messageIndex,
                                  autofocus: 1,
                              }))} title={__("Double click to edit", 'limb-chatbot')}>{message.input}</span>
                    </td>
                    <td className='lbaic-settings-a-ftds-table-nested-body-item lbaic-settings-a-ftds-table-output'>
                        <div className='lbaic-settings-a-ftds-table-flex'>
                            <span className='lbaic-settings-a-ftds-table-body-label'
                                  onDoubleClick={() => setEditMessage(prevState => ({
                                      data: {
                                          ...message,
                                      },
                                      index: messageIndex,
                                      autofocus: 2,
                                  }))} title={__("Double click to edit", 'limb-chatbot')}>{message.output}</span>
                            <div className='lbaic-settings-a-ftds-table-actions'>
                                <button className='lbaic-settings-a-ftds-table-action lbaic-settings-button-reset'
                                        onClick={() => updateMessage({
                                            ...message,
                                            weight: 1,
                                        }, messageIndex, index)}>
                                    <div className={`lbaic-settings-a-ftds-table-circle lbaic-settings-a-ftds-table-circle-primary${message.weight === 1 ? ' active' : ''}`}/>
                                </button>
                                <button className='lbaic-settings-a-ftds-table-action lbaic-settings-button-reset'
                                        onClick={() => updateMessage({
                                            ...message,
                                            weight: 0,
                                        }, messageIndex, index)}>
                                    <div className={`lbaic-settings-a-ftds-table-circle lbaic-settings-a-ftds-table-circle-secondary${message.weight === 0 ? ' active' : ''}`}/>
                                </button>
                            </div>
                        </div>
                    </td>
                </tr>
            }
        </>
    }

    return entry?.entry?.messages.length > 0 ?
        (<>
            {editMessage?.index === 0 ?
                <AddEditMessage message={editMessage.data} buttonLabel={__("Save", 'limb-chatbot')}
                                autofocusOn={editMessage.autofocus}
                                save={(data) => saveMessage(data, 0)} cancel={() => setEditMessage(null)}
                                notifications={notifications}/>
                :
                <tr key={index}
                    className={`lbaic-settings-a-ftds-table-body-in${showSubMessages || showSystemMessage ? ' active' : ''}`}>
                    <td className='lbaic-settings-a-ftds-table-body-item lbaic-settings-a-ftds-table-checkbox'>
                        <Checkbox className='lbaic-settings-dual-input-checkbox' isChecked={selected.indexOf(`${index}.0`) !== -1}
                                  toggleValue={() => {
                                      const i = selected.indexOf(`${index}.0`);
                                      if (i === -1) {
                                          setSelected(prevState => [...prevState, `${index}.0`]);
                                      } else {
                                          setSelected(prevState => prevState.filter(item => item !== `${index}.0`));
                                      }
                                  }}/>
                    </td>
                    <td className='lbaic-settings-a-ftds-table-body-item lbaic-settings-a-ftds-table-input'>
                        <span className='lbaic-settings-a-ftds-table-body-label'
                              onDoubleClick={() => setEditMessage(prevState => ({
                                  data: {
                                      ...entry.entry.messages[0],
                                  },
                                  index: 0,
                                  autofocus: 1,
                              }))} title={__("Double click to edit", 'limb-chatbot')}>{entry.entry.messages[0].input}</span>
                    </td>
                    <td className='lbaic-settings-a-ftds-table-body-item lbaic-settings-a-ftds-table-output'>
                        <div className='lbaic-settings-a-ftds-table-flex'>
                            <span className='lbaic-settings-a-ftds-table-body-label'
                                  onDoubleClick={() => setEditMessage(prevState => ({
                                      data: {
                                          ...entry.entry.messages[0],
                                      },
                                      index: 0,
                                      autofocus: 2,
                                  }))}
                                  title={__("Double click to edit", 'limb-chatbot')}>{entry.entry.messages[0].output}</span>
                            {defineAssistantPersona &&
                                <div className='lbaic-settings-a-ftds-table-actions'>
                                    <button className='lbaic-settings-a-ftds-table-action lbaic-settings-button-reset'
                                            onClick={() => updateMessage({
                                                ...entry.entry.messages[0],
                                                weight: 1,
                                            }, 0, index)}>
                                        <div
                                            className={`lbaic-settings-a-ftds-table-circle lbaic-settings-a-ftds-table-circle-primary${entry.entry.messages[0].weight === 1 ? ' active' : ''}`}/>
                                    </button>
                                    <button className='lbaic-settings-a-ftds-table-action lbaic-settings-button-reset'
                                            onClick={() => updateMessage({
                                                ...entry.entry.messages[0],
                                                weight: 0,
                                            }, 0, index)}>
                                        <div
                                            className={`lbaic-settings-a-ftds-table-circle lbaic-settings-a-ftds-table-circle-secondary${entry.entry.messages[0].weight === 0 ? ' active' : ''}`}/>
                                    </button>
                                    <button
                                        className={`lbaic-settings-a-ftds-table-action lbaic-settings-button-reset${showSystemMessage ? ' active' : ''}`}
                                        onClick={() => setShowSystemMessage(!showSystemMessage)}>
                                        <svg className='lbaic-settings-a-ftds-table-action-i' xmlns='http://www.w3.org/2000/svg'
                                             fill='none'
                                             viewBox='0 0 24 24'>
                                            <use href='#lbaic-settings-user'/>
                                        </svg>
                                    </button>
                                    <button
                                        className={`lbaic-settings-a-ftds-table-action lbaic-settings-button-reset${showSubMessages ? ' active' : ''}`}
                                        onClick={() => setShowSubMessages(!showSubMessages)}>
                                        <svg className='lbaic-settings-a-ftds-table-action-i' xmlns='http://www.w3.org/2000/svg'
                                             fill='none'
                                             viewBox='0 0 24 24'>
                                            <use href='#lbaic-settings-chat'/>
                                        </svg>
                                    </button>
                                </div>}
                        </div>
                    </td>
                </tr>}
            {(showSubMessages || showSystemMessage) &&
                <>
                    {showSystemMessage &&
                        <tr key={index + '-body-system-message'}
                            className='lbaic-settings-a-ftds-table-body-in lbaic-settings-a-ftds-table-body-border'>
                            <td className='lbaic-settings-a-ftds-table-body-item lbaic-settings-a-ftds-table-ai-textarea'>
                                <Copilot text={defaultSystemMessage}
                                         generated={text => {
                                             setSystemMessage(text, index);
                                             setDefaultSystemMessage(text);
                                         }}
                                         direction='right'
                                         notifications={notifications}/>
                            </td>
                            <td colSpan='2'
                                className='lbaic-settings-a-ftds-table-body-item lbaic-settings-a-ftds-table-textarea'>
                                <p className='lbaic-settings-a-ftds-table-textarea-in' data-placeholder=''
                                   contentEditable
                                   onInput={e => setSystemMessage(e.currentTarget.textContent, index)}>{defaultSystemMessage}</p>
                            </td>
                        </tr>
                    }
                    {showSubMessages &&
                        <>
                            {!!entry.entry.messages?.length && entry.entry.messages.map(renderSubMessage)}
                            <AddEditMessage buttonLabel={__("Add entry", 'limb-chatbot')}
                                            save={(data) => addMessage(data, index)}
                                            notifications={notifications}/>
                        </>
                    }
                </>
            }
        </>)
        :
        null // Skip the dataset entry from the list if has no any message
});

export default DatasetEntry;