import {forwardRef, useEffect, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import Dropdown from "../../dropdown";
import Tooltip from "../../tooltip";
import {GetChatbots, GetChatbot} from "../../../../rest/chatbots";
import {handleError} from "../../../../helpers/notifications";

const ChatbotField = forwardRef(({
    value,
    setValue,
    defaultValue,
    fieldProps = {},
    setLoading,
    notifications,
    disabled = false,
    placeholder = __("Chatbot", 'limb-chatbot'),
    required = true,
    className,
    children,
    onFetched
}, ref) => {
    // State
    const [chatbots, setChatbots] = useState([]);
    const [savedChatbot, setSavedChatbot] = useState(null);
    const [isFetched, setIsFetched] = useState(false);
    const [pagination, setPagination] = useState({
        page: 1,
        perPage: 10,
        total: 0,
    });

    useEffect(() => {
        getChatbots({
            page: 1,
            perPage: pagination.perPage
        }, true);
    }, []);

    useEffect(() => {
        if (value && !chatbots.find(item => item.uuid === value)) {
            getSavedChatbot(value);
        }
    }, [value, chatbots]);

    /**
     * Fetch chatbots
     */
    const getChatbots = async (params, reset = false) => {
        setLoading(prev => prev + 1);
        // Default params
        const reqParams = {
            page: params?.page || 1,
            per_page: params?.perPage || 10,
            include: ['default', 'utility'],
        };
        // Add search param
        if (params?.search) {
            reqParams.search = params.search;
            reqParams.search_fields = ['title'];
        }
        try {
            const res = await GetChatbots(LimbChatbot.rest.url, LimbChatbot.rest.nonce, reqParams);

            // Create chatbots array with default chatbot first
            let allChatbots = [];
            if (res._default) {
                // Add default chatbot as first item with uuid 'default'
                allChatbots.push({
                    ...res._default,
                    uuid: 'default',
                    title: res._default.utility?.title || __('Default Chatbot', 'limb-chatbot')
                });
            }
            // Add other chatbots
            if (res.items?.length) {
                allChatbots = [...allChatbots, ...res.items];
            }

            const newChatbots = [...(reset ? [] : chatbots), ...allChatbots];
            // Update state
            setChatbots([...newChatbots]);

            // Set default value if no value is set
            if (!value && newChatbots?.length) {
                // Default to the first item (which should be the default chatbot)
                setValue(newChatbots[0].uuid);
            }

            // Pagination info
            setPagination(prevState => ({
                ...prevState,
                page: reqParams.page,
                total: res.total,
            }));
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to retrieve chatbots data.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
            });
        }
        setTimeout(() => {
            setIsFetched(true);
            setLoading(prev => prev - 1);
            if (onFetched) {
                onFetched();
            }
        }, 200);
    }

    /**
     * Get saved chatbot
     *
     * @param {string} chatbotUuid Chatbot uuid
     * @return {Promise<void>}
     */
    const getSavedChatbot = async (chatbotUuid) => {
        try {
            // Handle default chatbot case
            if (chatbotUuid === 'default') {
                const res = await GetChatbots(LimbChatbot.rest.url, LimbChatbot.rest.nonce, {
                    include: ['default', 'utility'],
                    per_page: 1,
                });
                if (res?._default) {
                    setSavedChatbot({
                        ...res._default,
                        uuid: 'default',
                        title: res._default.utility?.title || __('Default Chatbot', 'limb-chatbot')
                    });
                }
            } else {
                const res = await GetChatbot(LimbChatbot.rest.url, LimbChatbot.rest.nonce, chatbotUuid);
                if (res?.uuid) {
                    setSavedChatbot(res);
                }
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Saved chatbot not found.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
            });
        }
    }

    /**
     * Handle chatbot selection
     *
     * @param {object} chatbot Selected chatbot
     */
    const handleChatbotSelection = (chatbot) => {
        setValue(chatbot.uuid);
    }

    return (
        <Dropdown 
            value={value}
            setValue={handleChatbotSelection}
            defaultValue={savedChatbot}
            options={chatbots.map(item => ({
                label: item.title,
                value: item.uuid,
                icon: item.utility?.icon ? 'chatbot-icon-' + item.utility.icon : undefined,
                extra: item,
            }))}
            placeholder={placeholder}
            searchable
            search={async (params) => await getChatbots(params, true)}
            loadMore={async (params) => await getChatbots(params)}
            pagination={{
                get: pagination,
                set: setPagination,
            }}
            className={className}
            disabled={disabled}
            {...fieldProps}
        >
            {children}
        </Dropdown>
    );
});

export default ChatbotField;
