import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Git Add Tool
 *
 * Stage files for commit.
 */
import { Box, Text } from 'ink';
import { useTerminalWidth } from '../../hooks/useTerminalWidth.js';
import { useTheme } from '../../hooks/useTheme.js';
import { jsonSchema, tool } from '../../types/core.js';
import { formatError } from '../../utils/error-formatter.js';
import { execGit, formatStatusChar, getDiffStats, parseGitStatus } from './utils.js';
// ============================================================================
// Execution
// ============================================================================
const executeGitAdd = async (args) => {
    try {
        const gitArgs = ['add'];
        if (args.all) {
            gitArgs.push('-A');
        }
        else if (args.update) {
            gitArgs.push('-u');
        }
        else if (args.files && args.files.length > 0) {
            gitArgs.push(...args.files);
        }
        else {
            // Default to staging all changes
            gitArgs.push('-A');
        }
        await execGit(gitArgs);
        // Get the new status to show what was staged
        const statusOutput = await execGit(['status', '--porcelain']);
        const { staged } = parseGitStatus(statusOutput);
        // Get diff stats for staged files
        const stats = await getDiffStats(true);
        for (const file of staged) {
            const fileStats = stats.get(file.path);
            if (fileStats) {
                file.additions = fileStats.additions;
                file.deletions = fileStats.deletions;
            }
        }
        if (staged.length === 0) {
            return 'No changes to stage.';
        }
        const totalAdditions = staged.reduce((sum, f) => sum + f.additions, 0);
        const totalDeletions = staged.reduce((sum, f) => sum + f.deletions, 0);
        const lines = [];
        lines.push(`Staged ${staged.length} file(s) (+${totalAdditions}, -${totalDeletions}):`);
        lines.push('');
        for (const file of staged.slice(0, 15)) {
            const char = formatStatusChar(file.status);
            const fileStats = file.additions || file.deletions
                ? ` (+${file.additions}, -${file.deletions})`
                : '';
            lines.push(`  ${char}  ${file.path}${fileStats}`);
        }
        if (staged.length > 15) {
            lines.push(`  ... and ${staged.length - 15} more files`);
        }
        return lines.join('\n');
    }
    catch (error) {
        return `Error: ${formatError(error)}`;
    }
};
// ============================================================================
// Tool Definition
// ============================================================================
const gitAddCoreTool = tool({
    description: 'Stage files for commit. Use files array for specific files, all=true for all changes including untracked, or update=true for only tracked files.',
    inputSchema: jsonSchema({
        type: 'object',
        properties: {
            files: {
                type: 'array',
                items: { type: 'string' },
                description: 'Specific files or patterns to stage',
            },
            all: {
                type: 'boolean',
                description: 'Stage all changes including untracked files (-A)',
            },
            update: {
                type: 'boolean',
                description: 'Stage only already tracked files (-u)',
            },
        },
        required: [],
    }),
    execute: async (args, _options) => {
        return await executeGitAdd(args);
    },
});
// ============================================================================
// Formatter
// ============================================================================
function GitAddFormatter({ args, result, }) {
    const boxWidth = useTerminalWidth();
    const { colors } = useTheme();
    // Parse result for display
    let fileCount = 0;
    let additions = 0;
    let deletions = 0;
    if (result) {
        const countMatch = result.match(/Staged (\d+) file/);
        if (countMatch)
            fileCount = parseInt(countMatch[1], 10);
        const statsMatch = result.match(/\(\+(\d+), -(\d+)\)/);
        if (statsMatch) {
            additions = parseInt(statsMatch[1], 10);
            deletions = parseInt(statsMatch[2], 10);
        }
    }
    // Determine mode
    let mode = 'all';
    if (args.files && args.files.length > 0) {
        mode = `${args.files.length} specific file(s)`;
    }
    else if (args.update) {
        mode = 'tracked files only';
    }
    return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, width: boxWidth, children: [_jsx(Text, { color: colors.tool, children: "\u2692 git_add" }), _jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: "Mode: " }), _jsx(Text, { color: colors.text, children: mode })] }), fileCount > 0 && (_jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: "Staging: " }), _jsxs(Text, { color: colors.text, children: [fileCount, " files "] }), _jsxs(Text, { color: colors.success, children: ["(+", additions] }), _jsx(Text, { color: colors.text, children: ", " }), _jsxs(Text, { color: colors.error, children: ["-", deletions] }), _jsx(Text, { color: colors.text, children: ")" })] })), result?.includes('No changes') && (_jsx(Box, { children: _jsx(Text, { color: colors.warning, children: "No changes to stage" }) }))] }));
}
const formatter = (args, result) => {
    return _jsx(GitAddFormatter, { args: args, result: result });
};
// ============================================================================
// Export
// ============================================================================
export const gitAddTool = {
    name: 'git_add',
    tool: gitAddCoreTool,
    formatter,
    // STANDARD - requires approval in normal mode, skipped in auto-accept
    approval: (_args, mode) => mode === 'normal',
};
//# sourceMappingURL=git-add.js.map