import type { OpenDialogOptions, Event } from 'electron'
import { dialog, ipcMain, shell, app } from 'electron'
import * as fs from 'fs-extra'
import * as path from 'path'

/** 当前项目文件夹锁：持有一个项目内文件的句柄，防止用户删除项目文件夹 */
let projectLockFd: number | null = null

/**
 * 选择文件夹
 */
export const choeseDirectory = async () => {
  const { canceled, filePaths } = await dialog.showOpenDialog({
    properties: ['openDirectory']
  })

  if (!canceled) {
    return filePaths[0]
  }
  return
}

/**
 * 选择文件
 */
export const choeseFile = async (_e: Event, options: OpenDialogOptions = {}) => {
  const { canceled, filePaths } = await dialog.showOpenDialog({
    title: '选择文件',
    buttonLabel: '选择',
    ...options
  })

  if (!canceled) {
    return filePaths
  }
  return
}

/**
 * 保存文件
 */
export const writeFile = async (_e: Event, filePath: string, content: string) => {
  return fs.writeFileSync(filePath, content)
}

/**
 * 读取文件
 */
export const readFile = async (_e: Event, filePath: string, encoding: BufferEncoding) => {
  return fs.readFileSync(filePath, { encoding })
}

/**
 * 检查文件是否存在
 */
export const checkFileExists = async (_e: Event, filePath: string) => {
  return fs.existsSync(filePath)
}

/**
 * 创建目录
 */
export const createDirectory = async (_e: Event, directoryPath: string) => {
  return fs.mkdirSync(directoryPath, { recursive: true })
}

/**
 * 复制文件
 */
export const copyFile = async (_e: Event, sourcePath: string, destinationPath: string) => {
  return fs.copyFileSync(sourcePath, destinationPath)
}

/**
 * 打开文件夹
 */
export const openDir = async (
  _e: Event,
  directoryPath: string,
  cb: (err: NodeJS.ErrnoException | null, dir: fs.Dir) => void
) => {
  return fs.opendir(directoryPath, cb)
}

/**
 * 复制文件夹
 */
export const cp = (_e: Event, sourcePath: string, destinationPath: string) => {
  return fs.cpSync(sourcePath, destinationPath)
}

/**
 * 删除文件
 */
export const removeFile = (_e: Event, sourcePath: string) => {
  return fs.rmSync(sourcePath)
}

/**
 * 打开并锁定文件
 */
export const openFile = (_e: Event, sourcePath: string, flag: string) => {
  return fs.openSync(sourcePath, flag || 'w')
}

/**
 * 关闭并解锁文件
 */
export const closeFile = (_e: Event, fd: number) => {
  return fs.closeSync(fd)
}

/**
 * 修改文件名
 */
export const renameFile = (_e: Event, sourcePath: string, targetPath: string) => {
  return fs.renameSync(sourcePath, targetPath)
}

/**
 * 资源管理器中打开
 * @param path 文件路径
 */
export const openFileInExplorer = (_e: Event, path: string) => {
  return shell.showItemInFolder(path)
}

/**
 * 锁定项目文件夹：打开项目目录内的 project.ui 并保持句柄，防止用户在资源管理器中删除该文件夹
 * @param projectDir 项目根目录路径（如 D:\projects\myProject）
 */
const lockProjectFolder = async (_e: Event, projectDir: string) => {
  if (projectLockFd !== null) {
    try {
      fs.closeSync(projectLockFd)
    } catch (_) {}
    projectLockFd = null
  }
  const lockFilePath = path.join(projectDir, 'project.ui')
  if (!fs.existsSync(lockFilePath)) return
  try {
    projectLockFd = fs.openSync(lockFilePath, 'r')
  } catch (_) {}
}

/**
 * 解锁项目文件夹：关闭句柄，允许用户删除项目文件夹
 */
export const unlockProjectFolder = () => {
  if (projectLockFd !== null) {
    try {
      fs.closeSync(projectLockFd)
    } catch (_) {}
    projectLockFd = null
  }
}

export const copyTemplate = async (_e: Event, targetPath: string) => {
  const templatePaths = app.isPackaged
    ? [
        path.join(process.resourcesPath, 'template/src'),
        path.join(process.resourcesPath, 'app.asar.unpacked/resources/template/src')
      ]
    : [path.join(process.cwd(), 'resources/template/src')]
  const templatePath = templatePaths.find((item) => fs.existsSync(item))

  await fs.ensureDir(targetPath)
  if (templatePath) {
    await fs.copy(templatePath, targetPath)
  }

  await fs.ensureDir(path.join(targetPath, 'assets/images'))
  await fs.ensureDir(path.join(targetPath, 'assets/fonts'))
  await fs.ensureDir(path.join(targetPath, 'assets/others'))
  // .gitkeep占位文件 创建后移除
  await fs.remove(path.join(targetPath, 'assets/images/.gitkeep'))
  await fs.remove(path.join(targetPath, 'assets/others/.gitkeep'))
}

export function handleFile() {
  // 获取文件夹
  ipcMain.handle('get-directory', choeseDirectory)
  // 获取文件
  ipcMain.handle('get-file', choeseFile)
  // 创建文件夹
  ipcMain.handle('create-directory', createDirectory)
  // 复制文件夹
  ipcMain.handle('copy-directory', cp)
  // 写入文件
  ipcMain.handle('write-file', writeFile)
  // 读取文件
  ipcMain.handle('read-file', readFile)
  // 检查路径是否存在
  ipcMain.handle('check-file-path', checkFileExists)
  // 复制文件
  ipcMain.handle('copy-file', copyFile)
  // 删除文件
  ipcMain.handle('delete-file', removeFile)
  // 独占打开
  ipcMain.handle('exclusive-open', openFile)
  // 独占关闭
  ipcMain.handle('exclusive-close', closeFile)
  // 修改文件名
  ipcMain.handle('modify-file-name', renameFile)
  // 资源管理器中打开
  ipcMain.handle('open-file-in-explorer', openFileInExplorer)
  // 锁定/解锁项目文件夹（防止用户删除正在使用的项目目录）
  ipcMain.handle('lock-project-folder', lockProjectFolder)
  // 解锁项目文件夹
  ipcMain.handle('unlock-project-folder', unlockProjectFolder)
  // 复制模板文件
  ipcMain.handle('copy-template', copyTemplate)
}
