import { z } from "zod";
import {
  formatProjectGraphDetail,
  formatResourceGraphDetail,
  type ProjectGraphSnapshot,
  type ResourceGraphSnapshot,
} from "./computation-graph-detail-support.js";
import { controllerProcedure } from "../trpc.js";

export function createComputationGraphDetailProcedures(input: {
  resourceGraphInputSchema: z.AnyZodObject;
  projectGraphInputSchema: z.AnyZodObject;
  readResourceGraphSnapshot: (
    ctx: any,
    input: any,
  ) => Promise<ResourceGraphSnapshot>;
  readProjectGraphSnapshot: (
    ctx: any,
    input: any,
  ) => Promise<ProjectGraphSnapshot>;
}) {
  const resourceGraphDetailInputSchema = input.resourceGraphInputSchema.extend({
    domain: z.string().trim().min(1).optional(),
    includeLinks: z.boolean().optional(),
  });

  const projectGraphDetailInputSchema = input.projectGraphInputSchema.extend({
    domain: z.string().trim().min(1).optional(),
    includeLinks: z.boolean().optional(),
  });

  return {
    getResourceDataDetail: controllerProcedure
      .input(resourceGraphDetailInputSchema)
      .query(async ({ ctx, input: procedureInput }) => {
        const graph = await input.readResourceGraphSnapshot(ctx, procedureInput);
        return formatResourceGraphDetail({
          resourceId: procedureInput.resourceId,
          graph,
          ...(typeof procedureInput.domain === "string" ? { domain: procedureInput.domain } : {}),
          ...(typeof procedureInput.includeLinks === "boolean"
            ? { includeLinks: procedureInput.includeLinks }
            : {}),
        });
      }),

    getProjectDataDetail: controllerProcedure
      .input(projectGraphDetailInputSchema)
      .query(async ({ ctx, input: procedureInput }) => {
        const graph = await input.readProjectGraphSnapshot(ctx, procedureInput);
        return formatProjectGraphDetail({
          projectId: procedureInput.projectId,
          graph,
          ...(typeof procedureInput.domain === "string" ? { domain: procedureInput.domain } : {}),
          ...(typeof procedureInput.includeLinks === "boolean"
            ? { includeLinks: procedureInput.includeLinks }
            : {}),
        });
      }),
  };
}
