import {useEffect, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import PopupContainer from "../../../../../../../../../popups/container";
import {renderEntryQuestion, renderSource} from "../../../../../../knowledge/sources/_renderers";
import Chip from "../../../../../../../../../fields/chip";
import RealTimeRelativeTime from "../../../../../../../../../fields/real-time-relative-time";
import DatasetEntryDetails
    from "../../../../../../knowledge/sources/_components/dataset-entries/dataset-entry-details";
import Table from "../../../../../../../../../sections/table";
import {handleError} from "../../../../../../../../../../helpers/notifications";
import {GetDataset} from "../../../../../../../../../../rest/datasets";
import {delay} from "../../../../../../../../../../../components/chatbots/includes/helpers";

export default function MessageSourcesPopup({datasetEntries, onClose, notifications}) {
    const [loading, setLoading] = useState(0);
    const [datasets, setDatasets] = useState({});
    const [isDatasetsFetched, setIsDatasetsFetched] = useState(false);

    useEffect(() => {
        fetchDatasets();
    }, []);

    /**
     * Fetch datasets
     *
     * @return {Promise<void>}
     */
    const fetchDatasets = async () => {
        setLoading(prev => prev + 1);
        await delay(2000);
        try {
            // Datasets objects
            const datasets = datasetEntries.reduce((acc, entry) => ({
                ...acc,
                [entry.dataset_id]: null,
            }), {});
            // Fetch datasets
            for (const datasetId in datasets) {
                const dataset = await fetchDataset(datasetId);
                if (dataset?.id) {
                    datasets[datasetId] = dataset;
                }
            }
            // Update datasets state
            setDatasets(datasets);
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to fetch datasets.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        }
        setLoading(prev => prev - 1);
        setIsDatasetsFetched(true);
    }

    /**
     * Fetch dataset
     *
     * @param {number} id Dataset ID
     * @return {Promise<void>}
     */
    const fetchDataset = async (id) => {
        try {
            const res = await GetDataset(LimbChatbot.rest.url, LimbChatbot.rest.nonce, id, {
                include: ['storage', 'source_object', 'source_url']
            });
            if (res?.dataset?.id) {
                return res.dataset;
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to get dataset.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again."),
            });
        }
        return null;
    }

    /**
     * Entry details updated
     */
    const entryDetailsUpdated = (entryData, rowId) => {
        try {
            const datasetEntry = datasetEntries.find(item => item.id === rowId);
            if (datasetEntry) {
                datasetEntry.entry = {
                    ...datasetEntry.entry,
                    ...entryData
                };
            }
        } catch (e) {
            handleError(e);
        }
    }

    const tableStructure = {
        columns: [
            {
                id: 'question',
                label: __("Question", 'limb-chatbot'),
                className: 'lbaic-settings-table-card-header-input',
                value: {
                    className: 'lbaic-settings-table-card-body-input lbaic-settings-cursor-pointer',
                    render: (row, index) => renderEntryQuestion(row),
                },
                detailsToggler: true,
            },
            {
                id: 'source',
                label: __("Source", 'limb-chatbot'),
                className: 'lbaic-settings-table-card-header-type',
                value: {
                    className: 'lbaic-settings-table-card-body-type',
                    render: (row, index) => renderSource(datasets[row.dataset_id], index, datasets[row.dataset_id]?.source_type === 'text' || datasets[row.dataset_id]?.source_type === 'q_a' ? 'chip' : 'label'),
                },
            },
            {
                id: 'updated_at',
                label: __("Updated at", 'limb-chatbot'),
                className: 'lbaic-settings-table-card-header-type',
                value: {
                    className: 'lbaic-settings-table-card-body-last-updated',
                    render: (row, index) => {
                        return <Chip>
                            <RealTimeRelativeTime
                                dateString={row.updated_at}
                                className='lbaic-settings-chip-label'
                            />
                        </Chip>
                    },
                },
            },
        ],
        row: {
            className: (row, index) => {
                let classes = 'lbaic-settings-table-accordion-body-in';

                return classes;
            },
            details: {
                show: true,
                render: (row, rowIndex, show) => {
                    return (
                        <DatasetEntryDetails
                            key={row.id}
                            row={row}
                            rowIndex={rowIndex}
                            show={show}
                            updated={entryDetailsUpdated}
                            notifications={notifications}
                            fullWidth
                        />
                    )
                }
            }
        },
    };

    return (
        <PopupContainer
            close={onClose}
            title={__('Sources', 'limb-chatbot')}
            loading={loading > 0}
            showLoadingContainer={!isDatasetsFetched && loading > 0}
            footer={
                <>
                    <div></div>
                    <button
                        type='button'
                        className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary'
                        onClick={onClose}
                    >
                        <span className='lbaic-settings-button-label'>{__("Close", 'limb-chatbot')}</span>
                    </button>
                </>
            }
            style={{
                '--lbaic-settings-popup-max-width': '612px'
            }}
        >
            <Table
                className='lbaic-settings-scroll-style lbaic-settings-scroll-x lbaic-settings-table-card-has-details lbaic-settings-table-card-dataset-entries'
                structure={tableStructure}
                loading={loading > 0}
                data={datasetEntries}
            />
        </PopupContainer>
    );
}
