import { LoaderFunctionArgs, json } from "@remix-run/server-runtime";
import { z } from "zod";
import { prisma } from "~/db.server";
import {
  authenticateRequest,
  authenticatedEnvironmentForAuthentication,
  branchNameFromRequest,
} from "~/services/apiAuth.server";
import { logger } from "~/services/logger.server";
import zlib from "node:zlib";

const ParamsSchema = z.object({
  projectRef: z.string(),
  envSlug: z.string(),
  version: z.string(),
});

export async function loader({ params, request }: LoaderFunctionArgs) {
  const parsedParams = ParamsSchema.safeParse(params);

  if (!parsedParams.success) {
    return json({ error: "Invalid params" }, { status: 400 });
  }

  try {
    const authenticationResult = await authenticateRequest(request);

    if (!authenticationResult) {
      return json({ error: "Invalid or Missing API key" }, { status: 401 });
    }

    const environment = await authenticatedEnvironmentForAuthentication(
      authenticationResult,
      parsedParams.data.projectRef,
      parsedParams.data.envSlug,
      branchNameFromRequest(request)
    );

    // Find the background worker and tasks and files
    const backgroundWorker = await prisma.backgroundWorker.findFirst({
      where: {
        runtimeEnvironmentId: environment.id,
        version: parsedParams.data.version,
      },
      include: {
        tasks: true,
        files: {
          include: {
            tasks: {
              select: {
                slug: true,
              },
            },
          },
        },
      },
    });

    if (!backgroundWorker) {
      return json({ error: "Background worker not found" }, { status: 404 });
    }

    return json({
      id: backgroundWorker.friendlyId,
      version: backgroundWorker.version,
      cliVersion: backgroundWorker.cliVersion,
      sdkVersion: backgroundWorker.sdkVersion,
      contentHash: backgroundWorker.contentHash,
      createdAt: backgroundWorker.createdAt,
      updatedAt: backgroundWorker.updatedAt,
      tasks: backgroundWorker.tasks.map((task) => ({
        id: task.slug,
        exportName: task.exportName ?? "@deprecated",
        filePath: task.filePath,
        source: task.triggerSource,
        retryConfig: task.retryConfig,
        queueConfig: task.queueConfig,
      })),
      files: backgroundWorker.files.map((file) => ({
        id: file.friendlyId,
        filePath: file.filePath,
        contentHash: file.contentHash,
        contents: decompressContent(file.contents),
        tasks: Array.from(new Set(file.tasks.map((task) => task.slug))),
      })),
    });
  } catch (error) {
    if (error instanceof Response) throw error;
    logger.error("Failed to load background worker", { error });
    return json({ error: "Internal Server Error" }, { status: 500 });
  }
}

function decompressContent(compressedBuffer: Uint8Array): string {
  // Convert Uint8Array to Buffer and decode base64 in one step
  const decodedBuffer = Buffer.from(Buffer.from(compressedBuffer).toString("utf-8"), "base64");

  // Decompress the data
  const decompressedData = zlib.inflateSync(decodedBuffer);

  // Convert the decompressed data to string
  return decompressedData.toString();
}
