import {__, sprintf} from "@wordpress/i18n";
import Chip from "../../../../../../fields/chip";
import Tooltip from "../../../../../../fields/tooltip";
import {handleError} from "../../../../../../../helpers/notifications";
import {
    DATASET_STATUS_FAILED,
    DATASET_STATUS_GENERATED,
    DATASET_STATUS_GENERATING,
    DATASET_STATUS_INDEXED,
    DATASET_STATUS_INDEXING,
    DATASET_STATUS_PENDING
} from "../../../../../../../rest/datasets";
import {DATASET_PROCESSES_INFO} from "../_data";
import {parseDateString} from "../../../../../../../../helpers";
import {FILES_TYPES_ICONS, WP_POST_TYPES_ICONS} from "../add-sources/_data";
import SourceLink from "./components/source-link";

/**
 * Render row content of the `Name` column
 *
 * @param {object} row Row data
 * @param {number} rowIndex Row index
 * @param {object} processInfo Process info
 * @return {JSX.Element}
 */
export const renderName = (row, rowIndex, processInfo = null) => {
    // Errors/warnings
    const errors = [], warnings = [];
    if (row.metas?.length) {
        for (const meta of row.metas) {
            if (meta.meta_key === 'errors') {
                if (meta.meta_value?.length) {
                    for (const error of meta.meta_value) {
                        // Show only error that isn't critical, critical once already shown with notifications
                        if (error.is_critical) {
                            errors.push(error.message);
                        } else {
                            warnings.push(error.message);
                        }
                    }
                }
                break;
            }
        }
    }

    if (row.status !== DATASET_STATUS_INDEXED) {
        // If is newly created and a process is currently going
        const {preparing, processState} = processInfo || {};
        const isInProcessRow =
            // Some process is currently active
            (
                processState?.status === 'start'
                || processState?.status === 'pause'
            )
            && (
                processState.datasetIds?.includes(row.id) // The process includes the current row
                || ( // Or newly created
                    processState.startedAt
                    && parseDateString(row.updated_at) > processState.startedAt
                )
            );

        // Show errors if it hasn't yet
        if (!isInProcessRow && !errors.length && !warnings.length) {
            if (row.status === DATASET_STATUS_PENDING) {
                warnings.push(sprintf(__("%s hasn't been started or completed.", 'limb-chatbot'), DATASET_PROCESSES_INFO['dataset_generating'].title));
            } else if (row.status === DATASET_STATUS_GENERATING) {
                warnings.push(sprintf(__("%s not complete.", 'limb-chatbot'), DATASET_PROCESSES_INFO['dataset_generating'].title));
            } else if (row.status === DATASET_STATUS_FAILED) {
                errors.push(__("Something went wrong!", 'limb-chatbot'));
            }
        }
    }

    // Notices
    let info = false;
    if (errors.length > 0 || warnings.length > 0) {
        info = <>
            {errors.length > 0 &&
                <Tooltip label={errors.map(item => __(item, 'limb-chatbot')).join('<br/>')}>
                    <svg className='lbaic-settings-tooltip-i lbaic-settings-error-i' xmlns='http://www.w3.org/2000/svg'
                         fill='none'
                         viewBox='0 0 24 24'>
                        <use href='#lbaic-settings-error'/>
                    </svg>
                </Tooltip>}
            {warnings.length > 0 &&
                <Tooltip label={warnings.join('<br/>')}>
                    <svg className='lbaic-settings-tooltip-i lbaic-settings-warning-i'
                         xmlns='http://www.w3.org/2000/svg'
                         fill='none'
                         viewBox='0 0 24 24'>
                        <use href='#lbaic-settings-warning'/>
                    </svg>
                </Tooltip>}
        </>
    }

    try {
        let link;
        if (row.source) {
            switch (row.source_type) {
                case 'post':
                    link = row.source_url || row.source_object?.link || row.source_object?.guid;
                    break;
                case 'term':
                    link = row.source_url || row.source_object?.link;
                    break;
                case 'link':
                    link = row.source;
                    break;
                case 'file':
                    link = row.source_url || row.source;
                    break;
                case 'q_a':
                case 'text':
                    break;
                case 'url':
                    link = row.source;
                    break;
                default:
                    break;
            }
        }

        const isTheRowOld = isOldRow(row);

        return <div className='lbaic-settings-table-card-body-item-in lbaic-settings-table-card-body-input-in'>
            {/*Info*/}
            {info && (
                <div className='lbaic-settings-table-card-body-label-actions'>
                    {info}
                </div>
            )}
            {/*Label*/}
            {Boolean(link) ? (
                <span className='lbaic-settings-table-card-body-label lbaic-settings-table-card-body-input-label'>
                    <SourceLink
                        name={row.name}
                        link={link}
                        _default={<Chip/>}
                    />
                </span>
            ) : (
                <span
                    className={`lbaic-settings-table-card-body-label lbaic-settings-table-card-body-label-edit${!row.name ? ' lbaic-settings-table-card-body-label-null' : ''}`}
                    dangerouslySetInnerHTML={{__html: row.name || __("N/A", 'limb-chatbot')}}/>
            )}
            {/*Icons*/}
            {!processInfo?.disabled && (
                (row.source_type === 'q_a' || !isTheRowOld) ? (
                    <div
                        className='lbaic-settings-table-card-actions-edit lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-minimal'>
                        <svg className='lbaic-settings-table-card-actions-edit-i' xmlns='http://www.w3.org/2000/svg'
                             fill='none'
                             viewBox='0 0 24 24'>
                            <use href='#lbaic-settings-edit'/>
                        </svg>
                    </div>
                ) : (
                    <div
                        className='lbaic-settings-table-card-actions-edit lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-minimal'>
                        {isTheRowOld && Boolean(row.dataset_entries_count) && (
                            <span className='lbaic-settings-table-card-actions-label'>{row.dataset_entries_count}</span>
                        )}
                        <svg className='lbaic-settings-table-card-actions-edit-i rotate'
                             xmlns='http://www.w3.org/2000/svg'
                             fill='none'
                             viewBox='0 0 24 24'>
                            <use href='#lbaic-settings-arrow'/>
                        </svg>
                    </div>
                )
            )}
        </div>;
    } catch (e) {
        handleError(e);
    }

    return <div className='lbaic-settings-table-card-body-item-in lbaic-settings-table-card-body-input-in'>
        {info && (
            <div className='lbaic-settings-table-card-body-label-actions'>
                {info}
            </div>
        )}
        <span
            className="lbaic-settings-table-card-body-label lbaic-settings-table-card-body-label-null">{__("N/A", 'limb-chatbot')}</span>
    </div>;
}

/**
 * Render row content of the `Source` column
 *
 * @param {object} row Row data
 * @param {number} index Row index
 * @param {string} type Render type
 * @return {JSX.Element}
 */
export const renderSource = (row, index, type = 'chip') => {
    if (type === 'chip') {
        let iconName, title;
        switch (row?.source_type) {
            case 'post':
                iconName = WP_POST_TYPES_ICONS.includes(row.source_sub_type) ? row.source_sub_type : 'settings';
                title = row.source_sub_type;
                break;
            case 'term':
                iconName = 'term';
                title = __('term', 'limb-chatbot');
                break;
            case 'link':
                iconName = 'external';
                title = __('external', 'limb-chatbot');
                break;
            case 'file':
                iconName = row.source_sub_type in FILES_TYPES_ICONS ? FILES_TYPES_ICONS[row.source_sub_type] : 'file';
                title = __('attachment', 'limb-chatbot');
                break;
            case 'text':
                iconName = 'text';
                title = __('text', 'limb-chatbot');
                break;
            case 'q_a':
                iconName = 'q_a';
                title = __("q/a", 'limb-chatbot');
                break;
            case 'url':
                iconName = 'source-url';
                title = __('URL', 'limb-chatbot');
                break;
            default:
                break;
        }

        return <Chip label={title} iconName={iconName}/>;
    } else if (type === 'label') {
        let link;
        if (row?.source) {
            switch (row.source_type) {
                case 'post':
                    link = row.source_url || row.source_object?.link || row.source_object?.guid;
                    break;
                case 'term':
                    link = row.source_url || row.source_object?.link;
                    break;
                case 'link':
                    link = row.source;
                    break;
                case 'file':
                    link = row.source_url || row.source;
                    break;
                case 'q_a':
                case 'text':
                    break;
                case 'url':
                    link = row?.source;
                    break;
                default:
                    break;
            }
        }

        return (
            <SourceLink
                name={row?.name}
                link={link}
                className='secondary'
                _default={<Chip/>}
            />
        );
    }
    return <Chip/>;
}

/**
 * Render row content of the `Storage` column
 *
 * @param {object} row Row data
 * @return {JSX.Element[]|JSX.Element}
 */
export const renderStorage = (row) => {
    if (row?.storage?.id) {
        return <Chip label={row.storage.vector_db_id || 'local'} iconName={row.storage.vector_db_id || 'wordpress'}/>;
    } else {
        return <Chip/>;
    }
}

/**
 * Render row content of the `AI` column
 *
 * @param {object} row Row data
 * @param {string|null} kbAIProviderId Knowledge settings AI provider ID
 * @return {JSX.Element}
 */
export const renderAIProvider = (row, kbAIProviderId) => {
    const rowAIProviderId = row?.ai_provider_id;
    const showWarning = kbAIProviderId && rowAIProviderId && rowAIProviderId !== kbAIProviderId;

    return (
        <div className='lbaic-settings-table-card-body-item-in lbaic-settings-table-card-body-ai-in'>
            {showWarning && (
                <Tooltip
                    label={__("This dataset was created using a different embedding model, so it won't be included in knowledge retrieval with the current Knowledge → Settings.", 'limb-chatbot')}
                    width={210}
                >
                    <svg className='lbaic-settings-tooltip-i lbaic-settings-warning-i'
                         xmlns='http://www.w3.org/2000/svg'
                         fill='none'
                         viewBox='0 0 24 24'>
                        <use href='#lbaic-settings-warning'/>
                    </svg>
                </Tooltip>
            )}
            {rowAIProviderId ? (
                <Chip label={rowAIProviderId} iconName={rowAIProviderId}/>
            ) : (
                <Chip/>
            )}
        </div>
    );
}

/**
 * Render dataset entry row question
 *
 * @param {object} row Dataset entry row data
 * @return {JSX.Element}
 */
export const renderEntryQuestion = (row) => {
    const question = row?.entry?.messages[0]?.input;

    return (
        <div className='lbaic-settings-table-card-body-item-in lbaic-settings-table-card-body-input-in'>
            <span
                className={`lbaic-settings-table-card-body-label${!question ? ' lbaic-settings-table-card-body-label-null' : ''}`}
            >
                {question || __("N/A", 'limb-chatbot')}
            </span>
            <div
                className='lbaic-settings-table-card-actions-edit lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-minimal'>
                <svg
                    className='lbaic-settings-table-card-actions-edit-i'
                    xmlns='http://www.w3.org/2000/svg'
                    fill='none'
                    viewBox='0 0 24 24'
                >
                    <use href='#lbaic-settings-edit'/>
                </svg>
            </div>
        </div>
    );
}

/**
 * Is old dataset (1.0.8 or less)
 *
 * @param {object} row Dataset
 * @return {boolean}
 */
export const isOldRow = (row) => {
    return !row.metas?.find(item => item.meta_key === 'source_content');
}