import {__} from "@wordpress/i18n";
import {handleError} from "../notifications";
import {GetSetting, GetSettings, UpdateSettings} from "../../rest/settings";
import {convertLinksToHTML, getSettingsLocalKey} from "../index";

/**
 * Handle request response
 *
 * @param {object} res Response
 * @return {Promise<*>}
 */
export const handleResponse = async (res) => {
    let data;
    // Parse response
    try {
        data = await res.json();
    } catch (e) {
        // Invalid response
        throw new Error(__("Something went wrong", 'limb-chatbot'));
    }
    if (!res.ok) {
        let message;
        if (data?.message) {
            message = data?.message;
        } else if (data?.data?.message) {
            message = data.data.message;
        } else if (data?.data?.details) {
            const messages = Object.values(data.data.details).filter(item => item?.message);
            if (messages.length) {
                message = messages.filter(item => item?.message).map(item => __(item.message, 'limb-chatbot')).join("<br/>");
            }
        }
        throw new Error(message ? convertLinksToHTML(message) : __("Something went wrong", 'limb-chatbot'));
    }
    return data;
}

/**
 * Get default setting from utility
 *
 * @param {string} utility Utility
 * @param {string} key Utility setting key
 * @param {any} defaultValue Setting default value
 * @return {Promise<*|boolean>}
 */
export const GetDefaultSetting = async (utility, key, defaultValue = false) => {
    try {
        // Get utility setting
        const setting = await GetSetting(LimbChatbot.rest.url, LimbChatbot.rest.nonce, `lbaic.utilities.${utility}`);
        if (setting?.value) {
            const aiProvider = setting.value;
            // Get default value
            const defaultSetting = await GetSetting(LimbChatbot.rest.url, LimbChatbot.rest.nonce, `lbaic.ai_providers.${aiProvider}.utilities.${utility}.${key}`);
            if (defaultSetting) {
                return defaultSetting.value;
            }
        }
    } catch (e) {
        handleError(e);
    }
    return defaultValue;
}

/**
 * Get default settings from utility
 *
 * @param {string} utility Utility
 * @param {object[]} settings Utility settings
 * @return {Promise<*|boolean>}
 * @constructor
 */
export const GetDefaultSettings = async (utility, settings) => {
    const keys = settings.map(item => item.key);
    const defaultValues = settings.reduce((acc, item) => ({
        ...acc,
        [item.key]: item.defaultValue,
    }), {});

    let aiProvider = '';
    // Get default AI provider id
    try {
        const setting = await GetSetting(LimbChatbot.rest.url, LimbChatbot.rest.nonce, `lbaic.utilities.${utility}.default.ai_provider_id`);
        if (setting?.value) {
            aiProvider = setting.value;
            // AI provider id default value
            defaultValues.ai_provider_id = aiProvider;
        }
    } catch (e) {
        handleError(e);

        return defaultValues;
    }
    // Get default values
    if (aiProvider) {
        try {
            const keysPrefix = `lbaic.ai_providers.${aiProvider}.utilities.${utility}`;
            const defaultSettings = await GetSettings(LimbChatbot.rest.url, LimbChatbot.rest.nonce, {
                key: keys.map(item => `${keysPrefix}.${item}`)
            });
            if (defaultSettings?.length) {
                const data = keys.reduce((acc, key) => {
                    const setting = defaultSettings.find(item => item.key === `${keysPrefix}.${key}`);
                    if (setting) {
                        acc[key] = setting.value;
                    } else {
                        acc[key] = defaultValues[key];
                    }
                    return acc;
                }, {});
                // AI provider id
                data.ai_provider_id = aiProvider;

                return data;
            }
        } catch (e) {
            handleError(e);
        }
    }

    return defaultValues;
}

/**
 * Get settings from utility
 *
 * @param {string} aiProvider AI provider
 * @param {string} utility Utility
 * @param {object[]} settings Utility settings
 * @return {Promise<*|boolean>}
 * @constructor
 */
export const GetUtilitySettings = async (aiProvider, utility, settings) => {
    // Prepare data
    const keys = settings.map(item => item.key);
    const defaultValues = settings.reduce((acc, item) => ({
        ...acc,
        [item.key]: item.defaultValue,
    }), {});

    try {
        const keysPrefix = `lbaic.ai_providers.${aiProvider}.utilities.${utility}`;
        // Get default values
        const defaultSettings = await GetSettings(LimbChatbot.rest.url, LimbChatbot.rest.nonce, {
            key: keys.map(item => `${keysPrefix}.${item}`)
        });
        if (defaultSettings?.length) {
            return keys.reduce((acc, item) => {
                // Find current setting saved default value
                const defaultSetting = defaultSettings.find(setting => {
                    const key = getSettingsLocalKey(setting.key, keysPrefix);
                    return key === item;
                });
                if (defaultSetting) {
                    // Saved default value
                    acc[item] = defaultSetting.value;
                } else {
                    // Provided default value
                    acc[item] = defaultValues[item];
                }
                return acc;
            }, {});
        }
    } catch (e) {
        handleError(e);
    }
    // Return default value
    return defaultValues;
}

/**
 * Save utilities settings
 *
 * @param {string} utility Utility name (copilot or embedding)
 * @param {string} aiProviderId AI provider ID
 * @param {object} settings Settings object with ai_model_id, config_id, and optionally dimension
 * @return {Promise<void>}
 */
export const SaveUtilitySettings = async (utility, aiProviderId, settings) => {
    if (!aiProviderId || !settings) {
        return;
    }

    const settingsToUpdate = [];

    // Save default AI provider ID
    settingsToUpdate.push({
        key: `lbaic.utilities.${utility}.default.ai_provider_id`,
        value: aiProviderId,
    });

    // Save utility-specific settings
    // ai_model_id is required, so we only save if it exists
    if (settings.ai_model_id) {
        settingsToUpdate.push({
            key: `lbaic.ai_providers.${aiProviderId}.utilities.${utility}.ai_model_id`,
            value: settings.ai_model_id,
        });
    }

    // config_id is optional, save it if provided (including 0, though unlikely)
    if (settings.config_id) {
        settingsToUpdate.push({
            key: `lbaic.ai_providers.${aiProviderId}.utilities.${utility}.config_id`,
            value: settings.config_id,
        });
    }

    // For embedding, also save dimension if provided
    if (utility === 'embedding' && settings.dimension) {
        settingsToUpdate.push({
            key: `lbaic.ai_providers.${aiProviderId}.utilities.${utility}.dimension`,
            value: settings.dimension,
        });
    }

    if (settingsToUpdate.length > 0) {
        try {
            await UpdateSettings(LimbChatbot.rest.url, LimbChatbot.rest.nonce, settingsToUpdate);
        } catch (e) {
            handleError(e);
        }
    }
}