import { MIN_PANE_HEIGHT, MIN_PANE_WIDTH } from './types';
/**
 * Decide what actions to take to spawn a new agent pane
 *
 * Respects maxPanes limit with LRU rotation:
 * - If current agent panes >= maxPanes, close oldest pane before spawning new one
 * - This implements LRU (Least Recently Used) rotation
 */
export function decideSpawnActions(state, sessionId, description, config, sessionMappings) {
    if (!state.mainPane) {
        return { canSpawn: false, actions: [], reason: 'Main pane not found.' };
    }
    if (state.windowWidth < config.mainPaneMinWidth + config.agentPaneMinWidth) {
        return { canSpawn: false, actions: [], reason: 'Window too small for split.' };
    }
    const capacity = calculateCapacity(state.windowWidth, state.windowHeight);
    if (capacity.total <= 0) {
        return { canSpawn: false, actions: [], reason: 'Window too small for agent panes.' };
    }
    // Determine effective max panes (user config or calculated capacity)
    const effectiveMaxPanes = config.maxPanes ?? capacity.total;
    const currentPaneCount = state.agentPanes.length;
    // Check if we need LRU rotation (at or over maxPanes limit)
    if (currentPaneCount >= effectiveMaxPanes) {
        // Find oldest pane to close (LRU rotation)
        const oldestMapping = pickOldestPane(sessionMappings);
        if (!oldestMapping) {
            // No tracked sessions, try replacement instead
            const replacement = pickReplacementPane(state, sessionMappings);
            if (!replacement) {
                return { canSpawn: false, actions: [], reason: 'No pane available to replace.' };
            }
            return {
                canSpawn: true,
                actions: [
                    {
                        type: 'replace',
                        paneId: replacement.paneId,
                        oldSessionId: replacement.sessionId,
                        newSessionId: sessionId,
                        description,
                    },
                ],
            };
        }
        // Close oldest pane, then spawn new one
        const actions = [
            {
                type: 'close',
                paneId: oldestMapping.paneId,
                sessionId: oldestMapping.sessionId,
            },
        ];
        // After closing, we'll have room to spawn
        // Determine where to spawn the new pane
        if (currentPaneCount === 1) {
            // After closing the only agent pane, split from main
            actions.push({
                type: 'spawn',
                sessionId,
                description,
                targetPaneId: state.mainPane.paneId,
                splitDirection: '-h',
            });
        }
        else {
            // Find a remaining pane to split (not the one being closed)
            const remainingPanes = state.agentPanes.filter((p) => p.paneId !== oldestMapping.paneId);
            const targetPane = pickBestSplitPane(remainingPanes);
            if (targetPane) {
                const splitDirection = chooseSplitDirection(targetPane, config.agentPaneMinWidth);
                actions.push({
                    type: 'spawn',
                    sessionId,
                    description,
                    targetPaneId: targetPane.paneId,
                    splitDirection,
                });
            }
            else {
                // Fallback: split from main pane
                actions.push({
                    type: 'spawn',
                    sessionId,
                    description,
                    targetPaneId: state.mainPane.paneId,
                    splitDirection: '-h',
                });
            }
        }
        return { canSpawn: true, actions };
    }
    // Under maxPanes limit - normal spawn logic
    if (state.agentPanes.length === 0) {
        if (!canSplitHorizontally(state.mainPane, config.agentPaneMinWidth)) {
            return { canSpawn: false, actions: [], reason: 'Main pane too narrow to split.' };
        }
        return {
            canSpawn: true,
            actions: [
                {
                    type: 'spawn',
                    sessionId,
                    description,
                    targetPaneId: state.mainPane.paneId,
                    splitDirection: '-h',
                },
            ],
        };
    }
    const targetPane = pickBestSplitPane(state.agentPanes);
    if (!targetPane) {
        return { canSpawn: false, actions: [], reason: 'No suitable pane to split.' };
    }
    const splitDirection = chooseSplitDirection(targetPane, config.agentPaneMinWidth);
    if (!canSplitPane(targetPane, splitDirection, config.agentPaneMinWidth)) {
        return { canSpawn: false, actions: [], reason: 'No suitable pane to split.' };
    }
    return {
        canSpawn: true,
        actions: [
            {
                type: 'spawn',
                sessionId,
                description,
                targetPaneId: targetPane.paneId,
                splitDirection,
            },
        ],
    };
}
/**
 * Calculate grid capacity based on window size
 */
export function calculateCapacity(windowWidth, windowHeight) {
    const reservedWidth = Math.floor(windowWidth * 0.5);
    const agentWidth = Math.max(0, windowWidth - reservedWidth);
    const cols = Math.floor(agentWidth / MIN_PANE_WIDTH);
    const rows = Math.floor(windowHeight / MIN_PANE_HEIGHT);
    return {
        cols: Math.max(0, cols),
        rows: Math.max(0, rows),
        total: Math.max(0, cols * rows),
    };
}
function pickBestSplitPane(panes) {
    if (panes.length === 0) {
        return undefined;
    }
    return panes.reduce((best, pane) => {
        const bestArea = best.width * best.height;
        const area = pane.width * pane.height;
        return area > bestArea ? pane : best;
    });
}
function chooseSplitDirection(pane, minAgentWidth) {
    const canSplitHorizontally = pane.width >= minAgentWidth * 2;
    const canSplitVertically = pane.height >= MIN_PANE_HEIGHT * 2;
    if (canSplitHorizontally && canSplitVertically) {
        return pane.width >= pane.height ? '-h' : '-v';
    }
    if (canSplitHorizontally)
        return '-h';
    if (canSplitVertically)
        return '-v';
    return '-h';
}
function canSplitPane(pane, direction, minAgentWidth) {
    if (direction === '-h') {
        return canSplitHorizontally(pane, minAgentWidth);
    }
    return pane.height >= MIN_PANE_HEIGHT * 2;
}
function canSplitHorizontally(pane, minAgentWidth) {
    return pane.width >= minAgentWidth * 2;
}
function pickReplacementPane(state, sessionMappings) {
    const panesById = new Set(state.agentPanes.map((pane) => pane.paneId));
    const candidates = sessionMappings.filter((mapping) => panesById.has(mapping.paneId));
    if (candidates.length === 0)
        return null;
    return candidates.reduce((oldest, entry) => entry.createdAt.getTime() < oldest.createdAt.getTime() ? entry : oldest);
}
/**
 * Pick the oldest pane from session mappings (LRU - Least Recently Used)
 * Used for rotation when maxPanes limit is reached
 */
function pickOldestPane(sessionMappings) {
    if (sessionMappings.length === 0)
        return null;
    return sessionMappings.reduce((oldest, entry) => entry.createdAt.getTime() < oldest.createdAt.getTime() ? entry : oldest);
}
//# sourceMappingURL=decision-engine.js.map