import type { FastifyInstance } from 'fastify';
import type {
  AdoptWorktreeRequest,
  CreateWorktreeRequest,
  CreateWorktreeResponse,
  WorktreeResponse,
  WorktreesListResponse,
} from '@arboretum/shared';
import type { WorktreeManager } from '../core/worktree-manager.js';
import { sendManagerError } from './repos.js';

export function registerWorktreeRoutes(app: FastifyInstance, wt: WorktreeManager): void {
  app.get('/api/v1/worktrees', async (): Promise<WorktreesListResponse> => ({ worktrees: await wt.listAllWorktrees() }));

  app.get('/api/v1/repos/:id/worktrees', async (req): Promise<WorktreesListResponse> => {
    const { id } = req.params as { id: string };
    return { worktrees: await wt.listRepoWorktrees(id) };
  });

  app.post('/api/v1/repos/:id/worktrees', async (req, reply) => {
    const { id } = req.params as { id: string };
    const body = req.body as Partial<CreateWorktreeRequest> | null;
    if (!body || typeof body.branch !== 'string' || body.branch.trim() === '') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'branch is required' } });
    }
    if (body.startSession != null && body.startSession !== 'claude' && body.startSession !== 'bash') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'startSession must be claude, bash or null' } });
    }
    try {
      const out = await wt.createWorktree(id, {
        branch: body.branch,
        newBranch: body.newBranch !== false, // défaut : créer la branche
        ...(body.baseRef !== undefined ? { baseRef: body.baseRef } : {}),
        ...(body.path !== undefined ? { path: body.path } : {}),
        ...(body.runHooks !== undefined ? { runHooks: body.runHooks } : {}),
        ...(body.preTrust !== undefined ? { preTrust: body.preTrust } : {}),
        ...(body.startSession !== undefined ? { startSession: body.startSession } : {}),
      });
      const res: CreateWorktreeResponse = out;
      return reply.status(201).send(res);
    } catch (err) {
      return sendManagerError(reply, err);
    }
  });

  app.post('/api/v1/repos/:id/worktrees/adopt', async (req, reply) => {
    const { id } = req.params as { id: string };
    const body = req.body as Partial<AdoptWorktreeRequest> | null;
    if (!body || typeof body.path !== 'string') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'path is required' } });
    }
    try {
      const out = await wt.adoptWorktree(id, {
        path: body.path,
        ...(body.runHooks !== undefined ? { runHooks: body.runHooks } : {}),
        ...(body.preTrust !== undefined ? { preTrust: body.preTrust } : {}),
      });
      const res: WorktreeResponse & { hookResults: typeof out.hookResults } = { worktree: out.worktree, hookResults: out.hookResults };
      return reply.send(res);
    } catch (err) {
      return sendManagerError(reply, err);
    }
  });

  app.post('/api/v1/repos/:id/worktrees/prune', async (req, reply) => {
    const { id } = req.params as { id: string };
    try {
      await wt.prune(id);
      return reply.send({ ok: true });
    } catch (err) {
      return sendManagerError(reply, err);
    }
  });

  app.delete('/api/v1/repos/:id/worktrees', async (req, reply) => {
    const { id } = req.params as { id: string };
    const query = req.query as { path?: string; force?: string };
    if (typeof query.path !== 'string') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'path query param is required' } });
    }
    try {
      await wt.deleteWorktree(id, query.path, query.force === 'true');
      return reply.send({ ok: true });
    } catch (err) {
      return sendManagerError(reply, err);
    }
  });
}
