import React from 'react';
import { sanitizePromptIdSegment } from '../utils/slashCommands';
const normalizeServerLabel = (value) => {
    if (typeof value !== 'string')
        return '';
    const normalized = value.trim();
    return normalized.length > 0 ? normalized : '';
};
export const useSlashCommands = ({ servers, additionalPrompts, resolvePromptFromServer }) => {
    const slashCommandOptions = React.useMemo(() => {
        const options = [];
        const usedIds = new Set();
        const registerId = (candidate) => {
            let unique = candidate;
            let attempt = 1;
            while (usedIds.has(unique)) {
                unique = `${candidate}-${attempt++}`;
            }
            usedIds.add(unique);
            return unique;
        };
        for (const server of servers) {
            const prompts = server.options.cachedPrompts ?? [];
            if (!prompts.length)
                continue;
            const rawLabel = server.options.serverName ?? server.options.url ?? 'Unnamed server';
            const serverLabel = normalizeServerLabel(rawLabel) || 'Unnamed server';
            for (const prompt of prompts) {
                const optionId = registerId(`${server.id}:${prompt.name}`);
                options.push({
                    id: optionId,
                    title: prompt.name,
                    description: prompt.description,
                    serverName: serverLabel,
                    serverId: server.id,
                    prompt
                });
            }
        }
        additionalPrompts.forEach((entry, index) => {
            const prompt = entry?.prompt;
            if (!prompt || typeof prompt.name !== 'string') {
                return;
            }
            const promptName = prompt.name.trim();
            if (promptName.length === 0) {
                return;
            }
            const explicitId = typeof entry.id === 'string' ? entry.id.trim() : '';
            const baseSegment = sanitizePromptIdSegment(explicitId || promptName);
            const fallbackSegment = baseSegment.length > 0 ? baseSegment : `prompt-${index}`;
            const baseIdentifier = `additional:${fallbackSegment}`;
            const optionId = registerId(baseIdentifier);
            const resolvedTitle = typeof entry.title === 'string' && entry.title.trim().length > 0
                ? entry.title.trim()
                : promptName;
            const resolvedDescription = entry.description ?? prompt.description;
            const resolvedGroupLabel = typeof entry.groupLabel === 'string' && entry.groupLabel.trim().length > 0
                ? entry.groupLabel.trim()
                : 'Custom prompts';
            let resolvePrompt;
            if (entry.resolvePrompt) {
                const localResolver = entry.resolvePrompt;
                resolvePrompt = async (args) => {
                    const result = await localResolver(args);
                    return result ?? entry.promptInstance;
                };
            }
            else if (entry.promptInstance) {
                const promptInstance = entry.promptInstance;
                resolvePrompt = async () => promptInstance;
            }
            options.push({
                id: optionId,
                title: resolvedTitle,
                description: resolvedDescription,
                serverName: resolvedGroupLabel,
                serverId: optionId,
                prompt,
                resolvePrompt
            });
        });
        return options.sort((a, b) => {
            const nameCompare = a.title.localeCompare(b.title, undefined, { sensitivity: 'base' });
            if (nameCompare !== 0) {
                return nameCompare;
            }
            return (a.serverName ?? '').localeCompare(b.serverName ?? '', undefined, { sensitivity: 'base' });
        });
    }, [servers, additionalPrompts]);
    const resolveForSubmission = React.useCallback(async (selection) => {
        if (!selection) {
            return {};
        }
        const { option, args } = selection;
        const orderedArgs = option.prompt.arguments ?? [];
        const normalizedArgs = {};
        const parts = [];
        const processArg = (name, rawValue) => {
            const value = (rawValue ?? '').trim();
            if (value.length === 0) {
                return;
            }
            normalizedArgs[name] = value;
            const escaped = value.replace(/"/g, '\\"');
            parts.push(`${name}="${escaped}"`);
        };
        for (const argDef of orderedArgs) {
            processArg(argDef.name, args[argDef.name]);
        }
        for (const [key, rawValue] of Object.entries(args)) {
            if (orderedArgs.some((arg) => arg.name === key))
                continue;
            processArg(key, rawValue);
        }
        const argsSuffix = parts.length > 0 ? ` ${parts.join(' ')}` : '';
        const commandText = `/${option.prompt.name}${argsSuffix}`;
        let resolvedPrompt;
        if (typeof option.resolvePrompt === 'function') {
            resolvedPrompt = await option.resolvePrompt(normalizedArgs);
        }
        else {
            if (!option.serverId) {
                throw new Error('The selected slash command is missing MCP server information.');
            }
            resolvedPrompt = await resolvePromptFromServer(option.serverId, option.prompt.name, normalizedArgs);
        }
        const payload = {
            id: option.id,
            name: option.prompt.name,
            title: option.title,
            serverId: option.serverId,
            serverName: option.serverName,
            description: option.description,
            args: Object.fromEntries(Object.entries(args).map(([key, value]) => [key, value.trim()])),
            resolvedPrompt: resolvedPrompt
                ? {
                    description: resolvedPrompt.description ?? undefined,
                    messages: Array.isArray(resolvedPrompt.messages) ? resolvedPrompt.messages : []
                }
                : undefined
        };
        return {
            commandText,
            payload,
            resolvedPrompt
        };
    }, [resolvePromptFromServer]);
    return {
        slashCommandOptions,
        resolveForSubmission
    };
};
