import { exec } from 'child_process';
import { promisify } from 'util';
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getPermissionManager } from '../../permission/index.js';

const execAsync = promisify(exec);

export const gitCommitTool: ToolWithMetadata = {
  name: 'git_commit',
  description: loadDescription('git_commit'),
  metadata: {
    name: 'git_commit',
    category: 'git',
    description: '提交 Git 变更',
    keywords: ['git', 'commit', '提交', 'save', '保存', 'snapshot'],
    deferLoading: false,
  },
  parameters: {
    message: {
      type: 'string',
      description: '提交信息（必填）',
      required: true,
    },
    amend: {
      type: 'boolean',
      description: '修改上次提交（--amend）',
      required: false,
    },
    all: {
      type: 'boolean',
      description: '自动暂存所有已跟踪文件的变更（-a）',
      required: false,
    },
  },
  execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
    const message = params.message as string;
    const amend = params.amend as boolean;
    const all = params.all as boolean;

    if (!message && !amend) {
      return {
        success: false,
        output: '',
        error: '提交信息是必填的（message 参数）',
      };
    }

    // 权限检查
    const permissionManager = getPermissionManager();
    const permResult = await permissionManager.checkGitPermission({
      operation: 'commit',
      message,
    });

    if (!permResult.allowed) {
      if (permResult.needsConfirmation) {
        return {
          success: false,
          output: '',
          error: `需要用户确认: git commit\n原因: ${permResult.reason || '需要权限确认'}`,
        };
      }
      return {
        success: false,
        output: '',
        error: `权限被拒绝: ${permResult.reason || '操作不被允许'}`,
      };
    }

    try {
      const args: string[] = ['commit'];

      if (all) {
        args.push('-a');
      }

      if (amend) {
        args.push('--amend');
        if (message) {
          args.push('-m', `"${message.replace(/"/g, '\\"')}"`);
        } else {
          args.push('--no-edit');
        }
      } else {
        args.push('-m', `"${message.replace(/"/g, '\\"')}"`);
      }

      const { stdout, stderr } = await execAsync(`git ${args.join(' ')}`, {
        cwd: process.cwd(),
        timeout: 30000,
      });

      return {
        success: true,
        output: stdout + (stderr ? `\n${stderr}` : ''),
      };
    } catch (error) {
      const execError = error as { stdout?: string; stderr?: string; message: string };

      // 检查是否是没有变更可提交
      if (execError.message?.includes('nothing to commit') ||
          execError.stderr?.includes('nothing to commit')) {
        return {
          success: false,
          output: '',
          error: '没有变更需要提交。请先使用 git_add 暂存文件。',
        };
      }

      return {
        success: false,
        output: execError.stdout || '',
        error: execError.stderr || execError.message,
      };
    }
  },
};
