import * as vscode from "vscode";
import * as path from "path";

/**
 * 创建文件(本来不存在的情况)
 */
export async function createFile(
  filePath: string,
  content: string = ""
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您创建文件了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 检测文件是否已存在
    try {
      await vscode.workspace.fs.stat(fileUri);
      throw new Error(`文件已存在: ${absolutePath}`);
    } catch (error: any) {
      // 如果文件不存在，继续创建
      if (error.code !== "FileNotFound") {
        throw error;
      }
    }

    // 确保目录存在
    const dirPath = path.dirname(absolutePath);
    const dirUri = vscode.Uri.file(dirPath);
    try {
      await vscode.workspace.fs.stat(dirUri);
    } catch {
      await vscode.workspace.fs.createDirectory(dirUri);
    }

    // 创建文件
    const contentBytes = Buffer.from(content, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, contentBytes);
  } catch (error) {
    throw error;
  }
}

/**
 * 创建文件（如果存在则覆盖）
 */
export async function createOrOverwriteFile(
  filePath: string,
  content: string = ""
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您创建文件了"
        );
      }
    }

    // 确保目录存在
    const dirPath = path.dirname(absolutePath);
    const dirUri = vscode.Uri.file(dirPath);
    try {
      await vscode.workspace.fs.stat(dirUri);
    } catch {
      await vscode.workspace.fs.createDirectory(dirUri);
    }

    // 创建或覆盖文件
    const fileUri = vscode.Uri.file(absolutePath);
    const contentBytes = Buffer.from(content, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, contentBytes);
  } catch (error) {
    throw error;
  }
}

/**
 * 创建目录
 */
export async function createDirectory(dirPath: string): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = dirPath;
    if (!path.isAbsolute(dirPath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, dirPath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您创建目录了"
        );
      }
    }

    const dirUri = vscode.Uri.file(absolutePath);

    // 检测创建目录是否存在
    try {
      const stat = await vscode.workspace.fs.stat(dirUri);
      if (stat.type === vscode.FileType.Directory) {
        throw new Error(`目录已存在: ${absolutePath}`);
      } else {
        throw new Error(`路径已存在且不是目录: ${absolutePath}`);
      }
    } catch (error: any) {
      // 如果目录不存在，继续创建
      if (error.code !== "FileNotFound") {
        throw error;
      }
    }

    // 创建目录
    await vscode.workspace.fs.createDirectory(dirUri);
  } catch (error) {
    throw error;
  }
}

/**
 * 批量创建文件
 */
export async function createMultipleFiles(
  files: { path: string; content: string }[]
): Promise<{ path: string; success: boolean; error?: string }[]> {
  const results = [];

  for (const file of files) {
    try {
      await createFile(file.path, file.content);
      results.push({ path: file.path, success: true });
    } catch (error) {
      results.push({
        path: file.path,
        success: false,
        error: error instanceof Error ? error.message : "未知错误",
      });
    }
  }

  return results;
}

// 删除文件
export async function deleteFile(filePath: string): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您删除文件了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 检查文件是否存在
    try {
      const stat = await vscode.workspace.fs.stat(fileUri);
      if (stat.type !== vscode.FileType.File) {
        throw new Error(`路径不是文件: ${absolutePath}`);
      }
    } catch (error) {
      throw new Error(`文件不存在: ${absolutePath}`);
    }

    // 删除文件
    await vscode.workspace.fs.delete(fileUri);
  } catch (error) {
    throw error;
  }
}

// 修改文件内容（完全替换）
export async function updateFile(
  filePath: string,
  content: string
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您修改文件了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 检查文件是否存在
    try {
      const stat = await vscode.workspace.fs.stat(fileUri);
      if (stat.type !== vscode.FileType.File) {
        throw new Error(`路径不是文件: ${absolutePath}`);
      }
    } catch (error) {
      throw new Error(`文件不存在: ${absolutePath}`);
    }

    // 修改文件内容
    const contentBytes = Buffer.from(content, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, contentBytes);
  } catch (error) {
    throw error;
  }
}

/**
 * 追加文件内容
 */
export async function appendToFile(
  filePath: string,
  content: string
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您追加文件内容了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 检查文件是否存在并读取原内容
    let existingContent = "";
    try {
      const contentBytes = await vscode.workspace.fs.readFile(fileUri);
      existingContent = Buffer.from(contentBytes).toString("utf-8");
    } catch (error) {
      throw new Error(`文件不存在: ${absolutePath}`);
    }

    // 追加内容
    const newContent = existingContent + content;
    const contentBytes = Buffer.from(newContent, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, contentBytes);
  } catch (error) {
    throw error;
  }
}

// 部分修改文件内容（查找替换）
export async function replaceFile(
  filePath: string,
  searchValue: string | RegExp,
  replaceValue: string
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您修改文件了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 读取文件内容
    let fileContent: string;
    try {
      const contentBytes = await vscode.workspace.fs.readFile(fileUri);
      fileContent = Buffer.from(contentBytes).toString("utf-8");
    } catch (error) {
      throw new Error(`文件不存在: ${absolutePath}`);
    }

    // 转义特殊字符，将字符串作为字面量处理
    const escapeRegExp = (str: string) => {
      return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    };

    // 替换内容 - 如果是字符串，先转义特殊字符
    let newContent: string;
    if (typeof searchValue === "string") {
      const escapedSearch = escapeRegExp(searchValue);
      newContent = fileContent.replace(
        new RegExp(escapedSearch, "g"),
        replaceValue
      );
    } else {
      newContent = fileContent.replace(searchValue, replaceValue);
    }

    // 检查是否有内容被替换
    if (fileContent === newContent) {
      throw new Error(`未找到要替换的内容: ${searchValue}`);
    }

    // 写回文件
    const contentBytes = Buffer.from(newContent, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, contentBytes);
  } catch (error) {
    throw error;
  }
}

// 在指定位置插入内容
export async function insertAtLine(
  filePath: string,
  lineNumber: number,
  content: string
): Promise<void> {
  try {
    // 如果是相对路径，转换为绝对路径
    let absolutePath = filePath;
    if (!path.isAbsolute(filePath)) {
      const workspaceFolders = vscode.workspace.workspaceFolders;
      if (workspaceFolders && workspaceFolders.length > 0) {
        absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
      } else {
        throw new Error(
          "请先打开一个文件夹作为工作区，这样我就能为您修改文件了"
        );
      }
    }

    const fileUri = vscode.Uri.file(absolutePath);

    // 读取文件内容
    let fileContent: string;
    try {
      const contentBytes = await vscode.workspace.fs.readFile(fileUri);
      fileContent = Buffer.from(contentBytes).toString("utf-8");
    } catch (error) {
      throw new Error(`文件不存在: ${absolutePath}`);
    }

    const lines = fileContent.split("\n");

    // 插入内容
    lines.splice(lineNumber, 0, content);

    // 写回文件
    const newContent = lines.join("\n");
    const newContentBytes = Buffer.from(newContent, "utf-8");
    await vscode.workspace.fs.writeFile(fileUri, newContentBytes);
  } catch (error) {
    throw error;
  }
}

/**
 * 重命名文件
 */
export async function renameFile(
  oldPath: string,
  newPath: string
): Promise<void> {
  try {
    // 如果是相对路径,转换为绝对路径
    let absoluteOldPath = oldPath;
    let absoluteNewPath = newPath;
    const workspaceFolders = vscode.workspace.workspaceFolders;
    if (workspaceFolders && workspaceFolders.length > 0) {
      const workspaceRoot = workspaceFolders[0].uri.fsPath;

      if (!path.isAbsolute(oldPath)) {
        absoluteOldPath = path.join(workspaceRoot, oldPath);
      }

      if (!path.isAbsolute(newPath)) {
        absoluteNewPath = path.join(workspaceRoot, newPath);
      }
    } else {
      throw new Error(
        "请先打开一个文件夹作为工作区，这样我就能为您重命名文件了"
      );
    }

    const oldUri = vscode.Uri.file(absoluteOldPath);
    const newUri = vscode.Uri.file(absoluteNewPath);

    // 检查原文件是否存在
    try {
      await vscode.workspace.fs.stat(oldUri);
    } catch (error) {
      throw new Error(`文件不存在: ${absoluteOldPath}`);
    }

    // 检查新文件名是否已存在
    try {
      await vscode.workspace.fs.stat(newUri);
      throw new Error(`目标文件已存在: ${absoluteNewPath}`);
    } catch (error: any) {
      // 如果文件不存在，继续重命名
      if (
        error.code !== "FileNotFound" &&
        !error.message.includes("目标文件已存在")
      ) {
        throw error;
      }
      if (error.message.includes("目标文件已存在")) {
        throw error;
      }
    }

    // 确保目标目录存在
    const newDir = path.dirname(absoluteNewPath);
    const newDirUri = vscode.Uri.file(newDir);
    try {
      await vscode.workspace.fs.stat(newDirUri);
    } catch {
      await vscode.workspace.fs.createDirectory(newDirUri);
    }

    // 重命名文件
    await vscode.workspace.fs.rename(oldUri, newUri, { overwrite: false });
  } catch (error) {
    throw error;
  }
}
