/**
 * POST /api/workspaces/[slug]/apps/[uuid]/exec
 *
 * Run a one-shot command inside an app container via `docker exec`
 * on the Coolify host (over SSH). The companion of `/logs` for the
 * write path.
 *
 * Body (JSON):
 *   command       string   required. Passed through `sh -lc`.
 *   service       string?  compose service to target (required when
 *                          the app has >1 container).
 *   user          string?  docker exec --user
 *   workdir       string?  docker exec --workdir
 *   timeout_ms    number?  default 60_000, max 600_000
 *   max_bytes     number?  default 1_000_000, max 5_000_000
 */

import { NextResponse } from 'next/server';
import { requireWorkspacePrincipal } from '@/lib/auth/workspace-auth';
import { getApplicationInProject, TenantError } from '@/lib/coolify';
import { execInCoolifyApp } from '@/lib/coolify-exec';
import { isCoolifySshConfigured } from '@/lib/coolify-ssh';

export async function POST(
  request: Request,
  { params }: { params: Promise<{ slug: string; uuid: string }> }
) {
  const { slug, uuid } = await params;
  const principal = await requireWorkspacePrincipal(request, { targetSlug: slug });
  if (principal instanceof NextResponse) return principal;

  const ws = principal.workspace;
  if (!ws.coolify_project_uuid) {
    return NextResponse.json({ error: 'Workspace has no Coolify project yet' }, { status: 503 });
  }
  if (!isCoolifySshConfigured()) {
    return NextResponse.json(
      { error: 'apps.exec requires SSH to the Coolify host, not configured on this deployment.' },
      { status: 501 },
    );
  }

  let body: Record<string, unknown>;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json({ error: 'Body must be JSON' }, { status: 400 });
  }

  const command = typeof body.command === 'string' ? body.command : '';
  if (!command) {
    return NextResponse.json({ error: 'command is required' }, { status: 400 });
  }
  const service = typeof body.service === 'string' && body.service.trim()
    ? body.service.trim()
    : undefined;
  const user = typeof body.user === 'string' && body.user.trim() ? body.user.trim() : undefined;
  const workdir = typeof body.workdir === 'string' && body.workdir.trim()
    ? body.workdir.trim()
    : undefined;
  const timeoutMs = Number.isFinite(Number(body.timeout_ms)) ? Number(body.timeout_ms) : undefined;
  const maxBytes = Number.isFinite(Number(body.max_bytes)) ? Number(body.max_bytes) : undefined;

  try {
    await getApplicationInProject(uuid, ws.coolify_project_uuid);
    const result = await execInCoolifyApp({
      appUuid: uuid,
      command,
      service,
      user,
      workdir,
      timeoutMs,
      maxBytes,
    });
    return NextResponse.json(result);
  } catch (err) {
    if (err instanceof TenantError) {
      return NextResponse.json({ error: err.message }, { status: 403 });
    }
    return NextResponse.json(
      { error: 'Failed to exec in container', details: err instanceof Error ? err.message : String(err) },
      { status: 502 },
    );
  }
}
