/**
 * Agent session / run listing for org admin.
 */
import type { PrismaClient } from "@prisma/client";

export async function listProjectSessions(
  prisma: PrismaClient,
  input: {
    readonly organizationId: string;
    readonly projectId: string;
    readonly limit?: number | undefined;
  },
) {
  const project = await prisma.project.findFirst({
    where: { id: input.projectId, organizationId: input.organizationId },
    select: { id: true },
  });
  if (project === null) {
    throw new Error(`project not found: ${input.projectId}`);
  }
  const limit = Math.min(Math.max(input.limit ?? 50, 1), 200);
  const sessions = await prisma.agentSession.findMany({
    where: { projectId: project.id, archivedAt: null },
    select: {
      id: true,
      provider: true,
      roleId: true,
      model: true,
      title: true,
      createdAt: true,
      updatedAt: true,
      _count: { select: { runs: true } },
    },
    orderBy: { updatedAt: "desc" },
    take: limit,
  });
  return sessions.map((s) => ({
    id: s.id,
    provider: s.provider,
    roleId: s.roleId,
    model: s.model,
    title: s.title,
    runCount: s._count.runs,
    createdAt: s.createdAt.toISOString(),
    updatedAt: s.updatedAt.toISOString(),
  }));
}

export async function getSessionDetail(
  prisma: PrismaClient,
  input: { readonly organizationId: string; readonly sessionId: string },
) {
  const session = await prisma.agentSession.findUnique({
    where: { id: input.sessionId },
    select: {
      id: true,
      provider: true,
      roleId: true,
      model: true,
      title: true,
      createdAt: true,
      updatedAt: true,
      archivedAt: true,
      project: {
        select: { id: true, name: true, organizationId: true },
      },
      runs: {
        select: {
          id: true,
          status: true,
          model: true,
          provider: true,
          inputTokens: true,
          outputTokens: true,
          costUsd: true,
          costSource: true,
          startedAt: true,
          finishedAt: true,
          error: true,
          usageFacts: {
            select: {
              id: true,
              occurredAt: true,
              kind: true,
              provider: true,
              model: true,
              inputTokens: true,
              outputTokens: true,
              quantity: true,
              unit: true,
              costUsd: true,
              costSource: true,
              capabilityId: true,
              correlationId: true,
            },
            orderBy: { occurredAt: "asc" },
          },
        },
        orderBy: { startedAt: "desc" },
        take: 100,
      },
    },
  });
  if (session === null || session.project.organizationId !== input.organizationId) {
    throw new Error(`session not found: ${input.sessionId}`);
  }
  return {
    id: session.id,
    provider: session.provider,
    roleId: session.roleId,
    model: session.model,
    title: session.title,
    createdAt: session.createdAt.toISOString(),
    updatedAt: session.updatedAt.toISOString(),
    archivedAt: session.archivedAt?.toISOString() ?? null,
    project: {
      id: session.project.id,
      name: session.project.name,
    },
    runs: session.runs.map((r) => ({
      id: r.id,
      status: r.status,
      model: r.model,
      provider: r.provider,
      inputTokens: r.inputTokens,
      outputTokens: r.outputTokens,
      costUsd: r.costUsd === null ? null : Number(r.costUsd),
      costSource: r.costSource,
      startedAt: r.startedAt.toISOString(),
      finishedAt: r.finishedAt?.toISOString() ?? null,
      error: r.error,
      usageFacts: r.usageFacts.map((f) => ({
        id: f.id,
        occurredAt: f.occurredAt.toISOString(),
        kind: f.kind,
        provider: f.provider,
        model: f.model,
        inputTokens: f.inputTokens,
        outputTokens: f.outputTokens,
        quantity: f.quantity === null ? null : Number(f.quantity),
        unit: f.unit,
        costUsd: f.costUsd === null ? null : Number(f.costUsd),
        costSource: f.costSource,
        capabilityId: f.capabilityId,
        correlationId: f.correlationId,
      })),
    })),
  };
}
