import { readFile } from 'node:fs/promises';
import { useCallback, useEffect, useRef, useState } from 'react';
import { DEFAULT_PORT, getVSCodeServer } from '../vscode/index.js';
/**
 * Hook to manage VS Code server integration
 */
export function useVSCodeServer({ enabled, port = DEFAULT_PORT, currentModel, currentProvider, onPrompt, onDiagnosticsReceived, }) {
    const serverRef = useRef(null);
    const [isConnected, setIsConnected] = useState(false);
    const [connectionCount, setConnectionCount] = useState(0);
    const [actualPort, setActualPort] = useState(null);
    // Store callbacks in refs to avoid re-creating server on callback changes
    const onPromptRef = useRef(onPrompt);
    const onDiagnosticsReceivedRef = useRef(onDiagnosticsReceived);
    const currentModelRef = useRef(currentModel);
    const currentProviderRef = useRef(currentProvider);
    // Keep refs up to date
    useEffect(() => {
        onPromptRef.current = onPrompt;
    }, [onPrompt]);
    useEffect(() => {
        onDiagnosticsReceivedRef.current = onDiagnosticsReceived;
    }, [onDiagnosticsReceived]);
    useEffect(() => {
        currentModelRef.current = currentModel;
    }, [currentModel]);
    useEffect(() => {
        currentProviderRef.current = currentProvider;
    }, [currentProvider]);
    // Initialize server on mount if enabled
    useEffect(() => {
        if (!enabled) {
            return;
        }
        const initServer = async () => {
            const server = await getVSCodeServer(port);
            serverRef.current = server;
            // Set up callbacks using refs
            server.onCallbacks({
                onPrompt: (prompt, context) => {
                    onPromptRef.current?.(prompt, context);
                },
                onDiagnosticsResponse: diagnostics => {
                    onDiagnosticsReceivedRef.current?.(diagnostics);
                },
                onConnect: () => {
                    setIsConnected(true);
                    setConnectionCount(server.getConnectionCount());
                    // Send current status
                    if (currentModelRef.current || currentProviderRef.current) {
                        server.sendStatus(currentModelRef.current, currentProviderRef.current);
                    }
                },
                onDisconnect: () => {
                    const hasConnections = server.hasConnections();
                    setIsConnected(hasConnections);
                    setConnectionCount(server.getConnectionCount());
                },
            });
            // Start the server
            await server.start();
            setActualPort(server.getPort());
        };
        void initServer();
        // Cleanup on unmount
        return () => {
            if (serverRef.current) {
                void serverRef.current.stop();
                serverRef.current = null;
            }
        };
    }, [enabled, port]);
    // Update status when model/provider changes
    useEffect(() => {
        if (serverRef.current && enabled && isConnected) {
            serverRef.current.sendStatus(currentModel, currentProvider);
        }
    }, [enabled, currentModel, currentProvider, isConnected]);
    const sendAssistantMessage = useCallback((content, isGenerating = false) => {
        if (serverRef.current && enabled) {
            serverRef.current.sendAssistantMessage(content, isGenerating);
        }
    }, [enabled]);
    const notifyFileChange = useCallback((filePath, originalContent, newContent, toolName, toolArgs) => {
        if (serverRef.current && enabled && isConnected) {
            return serverRef.current.sendFileChange(filePath, originalContent, newContent, toolName, toolArgs);
        }
        return null;
    }, [enabled, isConnected]);
    const requestDiagnostics = useCallback((filePath) => {
        if (serverRef.current && enabled) {
            serverRef.current.requestDiagnostics(filePath);
        }
    }, [enabled]);
    const updateStatus = useCallback(() => {
        if (serverRef.current && enabled) {
            serverRef.current.sendStatus(currentModel, currentProvider);
        }
    }, [enabled, currentModel, currentProvider]);
    return {
        isConnected,
        connectionCount,
        actualPort,
        requestedPort: port,
        sendAssistantMessage,
        notifyFileChange,
        requestDiagnostics,
        updateStatus,
    };
}
/**
 * Check if VS Code mode was requested via CLI flag
 */
export function isVSCodeModeEnabled() {
    return process.argv.includes('--vscode');
}
/**
 * Get VS Code server port from CLI args or default
 */
export function getVSCodePort() {
    const portArgIndex = process.argv.findIndex(arg => arg === '--vscode-port' || arg === '-p');
    if (portArgIndex !== -1 && process.argv[portArgIndex + 1]) {
        const port = parseInt(process.argv[portArgIndex + 1], 10);
        if (!isNaN(port) && port > 0 && port < 65536) {
            return port;
        }
    }
    return DEFAULT_PORT;
}
/**
 * Helper to create file change notification with automatic content reading
 */
export async function createFileChangeFromTool(filePath, newContent, _toolName, _toolArgs) {
    let originalContent = '';
    try {
        originalContent = await readFile(filePath, 'utf-8');
    }
    catch {
        // File doesn't exist or can't be read - that's fine for create operations
    }
    return {
        originalContent,
        newContent,
    };
}
//# sourceMappingURL=useVSCodeServer.js.map