// Wrappers REST typés pour le moteur git « IDE » (P7) + l'API fichiers (Monaco). Consommés par la
// vue Workspace (P8) et le panneau de commit (P9). Le worktree est désigné par son chemin absolu.
import type {
  WorktreeChangesResponse,
  FileDiffResponse,
  FileContentResponse,
  WriteFileResponse,
  WorktreeResponse,
} from '@arboretum/shared';
import { api } from './api.js';

const enc = encodeURIComponent;

export const gitApi = {
  changes: (repoId: string, wt: string): Promise<WorktreeChangesResponse> =>
    api.get(`/api/v1/repos/${repoId}/worktrees/changes?path=${enc(wt)}`),

  diff: (repoId: string, wt: string, file: string, staged = false): Promise<FileDiffResponse> =>
    api.get(`/api/v1/repos/${repoId}/worktrees/diff?path=${enc(wt)}&file=${enc(file)}&staged=${staged ? '1' : '0'}`),

  stage: (repoId: string, wt: string, files: string[]): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/stage`, { path: wt, files }),

  unstage: (repoId: string, wt: string, files: string[]): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/unstage`, { path: wt, files }),

  discard: (repoId: string, wt: string, files: string[], includeUntracked = false): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/discard`, { path: wt, files, includeUntracked }),

  commit: (repoId: string, wt: string, message: string, opts: { mode?: 'all' | 'staged'; amend?: boolean } = {}): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/commit`, { path: wt, message, ...opts }),

  fetch: (repoId: string, wt: string): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/fetch`, { path: wt }),

  pull: (repoId: string, wt: string, mode: 'ff-only' | 'rebase' = 'ff-only'): Promise<WorktreeResponse> =>
    api.post(`/api/v1/repos/${repoId}/worktrees/pull`, { path: wt, mode }),

  readFile: (repoId: string, wt: string, path: string): Promise<FileContentResponse> =>
    api.get(`/api/v1/repos/${repoId}/files/content?wt=${enc(wt)}&path=${enc(path)}`),

  // baseMtime : mtime lu au chargement ; le serveur refuse en 409 STALE_FILE si le fichier a changé depuis.
  writeFile: (repoId: string, wt: string, path: string, content: string, baseMtime?: number): Promise<WriteFileResponse> =>
    api.put(`/api/v1/repos/${repoId}/files/content`, { wt, path, content, ...(baseMtime != null ? { baseMtime } : {}) }),
};
