/**
 * 多块编辑工具
 *
 * 在单个文件中执行多个搜索替换操作
 */

import * as path from 'path';
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 {
  createSearchReplaceEdit,
  applyEdit,
  validateEdit,
  type SearchReplaceBlock,
} from '../../editors/index.js';

export const multiEditTool: ToolWithMetadata = {
  name: 'multi_edit',
  description: loadDescription('multi_edit'),
  metadata: {
    name: 'multi_edit',
    category: 'filesystem',
    description: '对文件执行多个搜索替换操作',
    keywords: [
      'multi',
      'edit',
      'batch',
      'replace',
      'refactor',
      '多处',
      '批量',
      '编辑',
      '替换',
      '重构',
    ],
    deferLoading: false,
  },
  parameters: {
    path: {
      type: 'string',
      description: '要编辑的文件路径',
      required: true,
    },
    edits: {
      type: 'array',
      description: '编辑操作数组，每个元素包含 search 和 replace 字段',
      required: true,
    },
  },
  execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
    const filePath = params.path as string;
    const editsParam = params.edits as unknown[];
    const cwd = process.cwd();
    const absolutePath = path.isAbsolute(filePath)
      ? filePath
      : path.join(cwd, filePath);

    // 解析编辑块
    const blocks: SearchReplaceBlock[] = [];
    try {
      for (const item of editsParam) {
        if (typeof item !== 'object' || item === null) {
          return {
            success: false,
            output: '',
            error: '每个编辑项必须是包含 search 和 replace 字段的对象',
          };
        }

        const edit = item as Record<string, unknown>;
        if (typeof edit.search !== 'string' || typeof edit.replace !== 'string') {
          return {
            success: false,
            output: '',
            error: '每个编辑项必须包含 search 和 replace 字符串字段',
          };
        }

        blocks.push({
          search: edit.search,
          replace: edit.replace,
        });
      }
    } catch (error) {
      return {
        success: false,
        output: '',
        error: `解析编辑参数失败: ${error instanceof Error ? error.message : String(error)}`,
      };
    }

    if (blocks.length === 0) {
      return {
        success: false,
        output: '',
        error: '至少需要一个编辑操作',
      };
    }

    // 创建编辑对象
    const edit = createSearchReplaceEdit(absolutePath, blocks);

    // 先验证
    const validation = await validateEdit(edit);
    if (!validation.valid) {
      const errorMessages = validation.errors
        .map((e) => {
          if (e.search) {
            const preview = e.search.length > 50 ? e.search.slice(0, 50) + '...' : e.search;
            return `${e.message}\n  搜索内容: "${preview}"`;
          }
          return e.message;
        })
        .join('\n');

      return {
        success: false,
        output: '',
        error: `验证失败:\n${errorMessages}`,
      };
    }

    // 权限检查
    const permissionManager = getPermissionManager();

    // 为每个块创建简要的变更描述
    const changesSummary = blocks
      .map((b, i) => {
        const searchPreview = b.search.length > 30 ? b.search.slice(0, 30) + '...' : b.search;
        const replacePreview = b.replace.length > 30 ? b.replace.slice(0, 30) + '...' : b.replace;
        return `${i + 1}. "${searchPreview}" -> "${replacePreview}"`;
      })
      .join('\n');

    const permResult = await permissionManager.checkFilePermission({
      operation: 'edit',
      path: absolutePath,
      workdir: cwd,
      oldContent: `[多处编辑 - ${blocks.length} 处修改]\n${changesSummary}`,
      newContent: '[见上方变更摘要]',
    });

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

    // 应用编辑
    const result = await applyEdit(edit, {
      validate: false, // 已经验证过了
      runDiagnostics: true,
    });

    if (!result.success) {
      return {
        success: false,
        output: '',
        error: result.error || '编辑失败',
      };
    }

    // 构建输出
    let output = `文件已编辑: ${absolutePath}\n`;
    output += `应用了 ${result.stats?.blocksApplied || blocks.length} 处修改\n`;
    output += `+${result.stats?.additions || 0} 行 / -${result.stats?.deletions || 0} 行`;

    if (result.diagnostics) {
      output += `\n\n⚠️ 代码检查发现问题，请修复:${result.diagnostics}`;
    }

    return {
      success: true,
      output,
    };
  },
};
