//! 工程系统 API — IPC invoke 封装(对标设计 §五工程系统 + Batch 10 文件浏览)
//
// 工程记录类型复用 df-storage::ProjectModuleRecord(字段一一对应)。
// 文件浏览(getModuleFileTree/readModuleFile)返回 serde_json::Value,前端按字段取用。

import { invoke } from '@tauri-apps/api/core'

/** 工程记录(对齐后端 df_storage::models::ProjectModuleRecord)。 */
export interface ProjectModuleRecord {
  id: string
  project_id: string
  name: string
  /** 工程目录绝对路径(本机) */
  path: string
  git_url: string | null
  /** 技术栈 JSON 字符串 */
  stack: string | null
  auto_detected: boolean
  sort_order: number
  created_at: string
  updated_at: string
}

/** 文件树单条目(单层;前端点击文件夹再懒加载下一层)。 */
export interface FileTreeEntry {
  /** 文件/目录名(不含路径) */
  name: string
  /** 相对工程根的路径(POSIX 风格,前端用作后续 sub_path / file_path) */
  path: string
  is_dir: boolean
  /** 字节数(文件夹恒为 0) */
  size: number
  /** Git 状态码(`git status --porcelain` 的 XY 两字符,如 " M"/"M "/"??");文件夹恒无 */
  git_status?: string
}

/** getModuleFileTree 返回结构。 */
export interface FileTreeResult {
  /** 相对工程根的当前目录路径(根目录为空串) */
  path: string
  entries: FileTreeEntry[]
}

/** readModuleFile 返回结构。 */
export interface ReadFileResult {
  path: string
  /** 文本内容(二进制文件为空串) */
  content: string
  /** 文件总字节数 */
  size: number
  is_binary: boolean
  /** 是否因超 1MB 被截断 */
  truncated: boolean
}

/** Git 改动文件项(对齐后端 GitChangedFile)。 */
export interface GitChangedFile {
  status: string
  path: string
}

/** 工程依赖关系记录(对齐后端 ModuleDependencyRecord)。 */
export interface ModuleDependencyRecord {
  id: string
  project_id: string
  from_module_id: string
  to_module_id: string
  dep_type: string
  label: string | null
  created_at: string
}

/** 最近提交项(对齐后端 GitRecentCommit)。 */
export interface GitRecentCommit {
  hash: string
  subject: string
  /** Unix 时间戳(秒) */
  timestamp: number
  /** 作者名 */
  author: string
}

/** getModuleGitStatus 返回结构。 */
export interface GitStatusResult {
  branch: string
  changed_files: GitChangedFile[]
  recent_commits: GitRecentCommit[]
  /** 当前 HEAD 的全量提交数(`git rev-list --count HEAD`)。0 = 非 git 仓库或命令失败。 */
  total_commits: number
  is_git_repo: boolean
}

export const moduleApi = {
  /** 新增工程(返回完整记录)。 */
  addProjectModule(input: {
    projectId: string
    name: string
    path: string
    gitUrl?: string | null
    stack?: string | null
  }): Promise<ProjectModuleRecord> {
    return invoke('add_project_module', { input })
  },

  /** 扫描项目绑定目录下的子仓库,自动创建工程记录(幂等)。返回新创建数量。 */
  scanProjectModules(projectId: string): Promise<number> {
    return invoke('scan_project_modules', { projectId })
  },

  /** 列出项目全部工程(按 sort_order ASC)。 */
  listProjectModules(projectId: string): Promise<ProjectModuleRecord[]> {
    return invoke('list_project_modules', { projectId })
  },

  /** 查询工程 Git 状态(分支/改动文件/最近提交;非 git 仓库返回 is_git_repo:false)。 */
  getModuleGitStatus(moduleId: string): Promise<GitStatusResult> {
    return invoke('get_module_git_status', { moduleId })
  },

  /**
   * 列出工程文件树(单层 + git 状态合并)。
   * @param moduleId 工程 id
   * @param subPath 相对工程根的子路径(钻入子目录);省略/空 = 工程根
   */
  getModuleFileTree(moduleId: string, subPath?: string): Promise<FileTreeResult> {
    return invoke('get_module_file_tree', {
      moduleId,
      subPath: subPath && subPath.length > 0 ? subPath : null,
    })
  },

  /**
   * 读工程内单文件(文本/图片;1MB 上限,二进制检测)。
   * @param moduleId 工程 id
   * @param filePath 相对工程根的文件路径(POSIX 风格)
   */
  readModuleFile(moduleId: string, filePath: string): Promise<ReadFileResult> {
    return invoke('read_module_file', { moduleId, filePath })
  },

  /** 查询工程内文件元信息(不读内容,前端检测外部变化用)。返回 { path, size, modified_at }。 */
  getModuleFileMeta(moduleId: string, filePath: string): Promise<{ path: string; size: number; modified_at: number }> {
    return invoke('get_module_file_meta', { moduleId, filePath })
  },

  /** 查询工程内文件的 git diff(轻量,不读文件内容)。返回 { path, diff }。 */
  getModuleFileDiff(moduleId: string, filePath: string): Promise<{ path: string; diff: string }> {
    return invoke('get_module_file_diff', { moduleId, filePath })
  },

  /** 更新工程记录。 */
  updateProjectModule(input: {
    id: string
    name?: string
    path?: string
    gitUrl?: string | null
    stack?: string | null
  }): Promise<ProjectModuleRecord> {
    return invoke('update_project_module', { input })
  },

  /** 删除工程记录。 */
  removeProjectModule(moduleId: string): Promise<void> {
    return invoke('remove_project_module', { id: moduleId })
  },

  /** 分页查询工程 Git 提交历史。返回 { commits, has_more }。 */
  /** 列出工程本地分支(只读)。返回 { current, branches: [{ name, is_current }] }。 */
  listBranches(moduleId: string): Promise<{ current: string; branches: { name: string; is_current: boolean }[] }> {
    return invoke('list_branches', { moduleId })
  },

  /** 检测工程依赖环形依赖,返回参与环的 module_id 列表(空=无环)。 */
  detectModuleCycles(projectId: string): Promise<string[]> {
    return invoke('detect_module_cycles', { projectId })
  },

  /** 列出项目全部工程依赖。 */
  listModuleDependencies(projectId: string): Promise<ModuleDependencyRecord[]> {
    return invoke('list_module_dependencies', { projectId })
  },

  /** 新增工程依赖。 */
  addModuleDependency(projectId: string, fromModuleId: string, toModuleId: string, depType?: string, label?: string): Promise<ModuleDependencyRecord> {
    return invoke('add_module_dependency', { projectId, fromModuleId, toModuleId, depType: depType ?? null, label: label ?? null })
  },

  /** 删除工程依赖。 */
  removeModuleDependency(id: string): Promise<void> {
    return invoke('remove_module_dependency', { id })
  },

  getModuleCommits(moduleId: string, skip?: number, limit?: number): Promise<{
    commits: { hash: string; subject: string; timestamp: number; author: string }[]
    has_more: boolean
    /** 当前 HEAD 的全量提交数(`git rev-list --count HEAD`)。0 = 非 git 仓库或命令失败。 */
    total: number
  }> {
    return invoke('get_module_commits', { moduleId, skip: skip ?? 0, limit: limit ?? 50 })
  },

  /** 查询某次提交的变更文件列表及 diff。返回 { files: [{ status, path }], diff: string }。 */
  getCommitDetail(moduleId: string, commitHash: string): Promise<{
    files: { status: string; path: string }[]
    diff: string
    parents: string[]
    author: string
    date: string
    full_message: string
  }> {
    return invoke('get_commit_detail', { moduleId, commitHash })
  },
}
