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';
import type { GitOperation } from '../../permission/types.js';

const execAsync = promisify(exec);

export const gitStashTool: ToolWithMetadata = {
  name: 'git_stash',
  description: loadDescription('git_stash'),
  metadata: {
    name: 'git_stash',
    category: 'git',
    description: '暂存工作区变更',
    keywords: ['git', 'stash', '暂存', '保存', 'save', 'temporary', '临时'],
    deferLoading: false,
  },
  parameters: {
    action: {
      type: 'string',
      description: '操作类型: push（默认）, pop, list, apply, drop, clear',
      required: false,
    },
    message: {
      type: 'string',
      description: '暂存说明（push 时可用）',
      required: false,
    },
    index: {
      type: 'number',
      description: '暂存索引（pop/apply/drop 时可用，默认 0）',
      required: false,
    },
    include_untracked: {
      type: 'boolean',
      description: '包含未跟踪的文件（-u）',
      required: false,
    },
  },
  execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
    const action = (params.action as string) || 'push';
    const message = params.message as string | undefined;
    const index = params.index as number | undefined;
    const includeUntracked = params.include_untracked as boolean;

    // 确定权限操作类型
    let operation: GitOperation = 'stash';
    if (action === 'pop' || action === 'apply') {
      operation = 'stash_pop';
    }

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

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

    try {
      let command: string;
      const stashRef = index !== undefined ? `stash@{${index}}` : '';

      switch (action) {
        case 'push':
        case 'save':
          const pushArgs = ['stash', 'push'];
          if (includeUntracked) {
            pushArgs.push('-u');
          }
          if (message) {
            pushArgs.push('-m', `"${message.replace(/"/g, '\\"')}"`);
          }
          command = `git ${pushArgs.join(' ')}`;
          break;

        case 'pop':
          command = `git stash pop ${stashRef}`.trim();
          break;

        case 'apply':
          command = `git stash apply ${stashRef}`.trim();
          break;

        case 'drop':
          command = `git stash drop ${stashRef}`.trim();
          break;

        case 'list':
          command = 'git stash list';
          break;

        case 'clear':
          command = 'git stash clear';
          break;

        case 'show':
          command = `git stash show -p ${stashRef}`.trim();
          break;

        default:
          return {
            success: false,
            output: '',
            error: `未知操作: ${action}。支持的操作: push, pop, apply, drop, list, clear, show`,
          };
      }

      const { stdout, stderr } = await execAsync(command, {
        cwd: process.cwd(),
        timeout: 30000,
        maxBuffer: 1024 * 1024 * 10,
      });

      let output = stdout;

      // 针对不同操作给出友好输出
      if (!output) {
        switch (action) {
          case 'push':
          case 'save':
            output = '工作区变更已暂存';
            break;
          case 'pop':
            output = '暂存已恢复并删除';
            break;
          case 'apply':
            output = '暂存已恢复（暂存记录保留）';
            break;
          case 'drop':
            output = '暂存已删除';
            break;
          case 'clear':
            output = '所有暂存已清除';
            break;
          case 'list':
            output = '(无暂存记录)';
            break;
        }
      }

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

      // 检查常见错误
      if (errorMsg.includes('No local changes') || errorMsg.includes('no changes')) {
        return {
          success: false,
          output: '',
          error: '没有需要暂存的变更',
        };
      }

      if (errorMsg.includes('CONFLICT') || errorMsg.includes('conflict')) {
        return {
          success: false,
          output: execError.stdout || '',
          error: `恢复暂存时发生冲突，请手动解决。\n${errorMsg}`,
        };
      }

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