import {useEffect, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import {GetConfigs, UpdateConfig} from "../../../../../../../rest/configs";
import {handleError} from "../../../../../../../helpers/notifications";
import ContentBodyInner from "../../../../containers/content/body-inner";
import Container from "../../../../containers/content/container";
import Empty from "../../../../containers/content/empty";
import AddEditConfig from "../../../../../../popups/ai-providers/models/add-edit-config";
import ContentLoading from "../../../../containers/content/loading";
import ContentFooterLayout from "../../../../containers/content/footer/_components/layout";

export default function GeminiConfigs({notifications}) {
    // Actions states
    const [isDataFetched, setIsDataFetched] = useState(false);
    const [loading, setLoading] = useState(0);
    const [showEditConfigPopup, setShowEditConfigPopup] = useState(false);
    const [editConfigData, setEditConfigData] = useState(null);
    // Data
    const [configs, setConfigs] = useState([]);

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

    /**
     * Get gemini configs
     */
    const fetchConfigs = () => {
        setLoading(prev => prev + 1);
        GetConfigs(LimbChatbot.rest.url, LimbChatbot.rest.nonce, {
            related_to: 'gemini',
            page: 1,
            per_page: 10,
        }).then(res => {
            if (res.items?.length) {
                setConfigs(res.items);
            } else {
                setConfigs([]);
            }
            setIsDataFetched(true);
            setLoading(prev => prev - 1);
        }).catch(e => {
            setConfigs([]);
            setIsDataFetched(true);
            setLoading(prev => prev - 1);
            handleError(e, notifications.set, {
                title: __("Failed to retrieve API keys data.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check your connection and try again.", 'limb-chatbot'),
            });
        });
    }

    /**
     * Toggle edit config popup
     *
     * @param {object} config Config to edit
     */
    const toggleEditConfigPopup = (config) => {
        setEditConfigData(config);
        setShowEditConfigPopup(true);
    }

    /**
     * Make config default
     *
     * @param {object} config Config
     */
    const makeDefault = (config) => {
        UpdateConfig(LimbChatbot.rest.url, LimbChatbot.rest.nonce, config.id, {
            default: 1
        }).then(res => {
            setConfigs(prevState => prevState.map(item => ({
                ...item,
                default: +(item.id === config.id)
            })));
        }).catch(e => {
            handleError(e, notifications.set, {
                title: __("Failed to make it default.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please try again.", 'limb-chatbot'),
            });
        });
    }

    /**
     * Add new created config
     *
     * @param {object} newConfig New config data
     */
    const configAdded = (newConfig) => {
        setConfigs(prev => [...(newConfig.default ? prev.map(item => item.default ? {
            ...item,
            default: 0, // The new config is set as the default, so update the previous one to a non-default one
        } : item) : prev), newConfig]);
    }

    /**
     * Config updated
     *
     * @param {object} config Updated config data
     */
    const configUpdated = (config) => {
        setConfigs(prevState => prevState.map(item => item.id === config.id ? config : item));
    }

    /**
     * Config deleted
     *
     * @param {string} configId Deleted config Id
     */
    const configDeleted = (configId) => {
        // TODO -> which one is default now?
        setConfigs(prevState => prevState.filter(item => item.id !== configId));
    }

    /**
     * Close edit config popup
     */
    const closeEditConfigPopup = () => {
        setShowEditConfigPopup(false);
        setEditConfigData(null);
    }

    /**
     * Render config
     *
     * @param {object} config Config
     * @return {JSX.Element}
     */
    const renderConfig = (config) => {
        return <div key={config.id} className={`lbaic-settings-ap-c-item${config.default ? ' active' : ''}`}>
            <div className='lbaic-settings-ap-c-item-header'>
                <div className='lbaic-settings-ap-c-item-header-in'>
                    <span className='lbaic-settings-ap-c-item-header-label'>{config.title}</span>
                </div>
                <div className='lbaic-settings-ap-c-item-actions'>
                    <button
                        className={`lbaic-settings-ap-c-item-actions-in lbaic-settings-button-reset${config.default ? ' lbaic-settings-ap-c-item-actions-checked' : ''}`}
                        onClick={() => {
                            if (!config.default) {
                                makeDefault(config);
                            }
                        }}>
                        <svg className='lbaic-settings-ap-c-item-actions-i'
                             xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                            <use href='#lbaic-settings-checkbox-check-rounded'/>
                        </svg>
                    </button>
                    <button className='lbaic-settings-ap-c-item-actions-in lbaic-settings-button-reset'
                            onClick={() => toggleEditConfigPopup(config)}>
                        <svg className='lbaic-settings-ap-c-item-actions-i'
                             xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                            <use href='#lbaic-settings-edit'/>
                        </svg>
                    </button>
                </div>
            </div>
            <div className='lbaic-settings-ap-c-item-body'>
                <p className='lbaic-settings-ap-c-item-desc api-key'>{config.params?.api_key || 'API key not found'}</p>
                {!!config.description &&
                    <p className='lbaic-settings-ap-c-item-desc'>{config.description}</p>}
            </div>
        </div>
    }

    return <>
        <ContentBodyInner>
            {loading > 0 && !isDataFetched && <ContentLoading/>}
            <Container className='lbaic-settings-e-gc'>
                {
                    configs.length ? (
                        <div className='lbaic-settings-ap-c-item-grid'>
                            {configs.map(renderConfig)}
                        </div>
                    ) : (
                        isDataFetched && (
                            <Empty title={__("No API keys yet", 'limb-chatbot')}
                                   subtitle={__("Start by adding your first one", 'limb-chatbot')}
                                   icon="tab-configs-active">
                                <div className='lbaic-settings-empty-actions'>
                                    <button onClick={() => setShowEditConfigPopup(true)}
                                            className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary'>
                                        <span
                                            className='lbaic-settings-button-label'>{__("Add new API key", 'limb-chatbot')}</span>
                                    </button>
                                </div>
                            </Empty>
                        )
                    )
                }
            </Container>
        </ContentBodyInner>
        {configs.length > 0 &&
            <ContentFooterLayout loading={loading > 0}>
                <button onClick={() => setShowEditConfigPopup(true)}
                        className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary lbaic-settings-content-footer-actions-in${loading > 0 ? ' lbaic-settings-button-disabled' : ''}`}>
                    <span className='lbaic-settings-button-label'>{__("Add new key", 'limb-chatbot')}</span>
                </button>
            </ContentFooterLayout>}
        {showEditConfigPopup &&
            <AddEditConfig aiProviderId="gemini" added={configAdded} updated={configUpdated} deleted={configDeleted}
                           close={closeEditConfigPopup} configData={editConfigData} notifications={notifications}
                           showMakeDefault={true}/>}
    </>
}