import http from "node:http";
import { LaravelClient } from "./api/laravel-client.js";
import { RenderQueueConsumer } from "./api/redis-queue.js";
import { assertWorkerConfig, config } from "./config.js";
import { processRenderJob } from "./render/process-job.js";

const api = new LaravelClient();
const queue = new RenderQueueConsumer();

const inFlight = new Set<string>();
const startedAt = new Date().toISOString();

async function claimViaPolling(): Promise<string | null> {
  const jobs = await api.fetchQueuedJobs();
  const next = jobs.find((job) => !inFlight.has(job.uuid));

  return next?.uuid ?? null;
}

async function handleJob(renderJobUuid: string): Promise<void> {
  if (inFlight.has(renderJobUuid)) {
    return;
  }

  inFlight.add(renderJobUuid);

  try {
    await processRenderJob(renderJobUuid, api);
  } finally {
    inFlight.delete(renderJobUuid);
  }
}

async function loop(): Promise<void> {
  while (true) {
    const message = await queue.popJob();
    const renderJobUuid = message?.render_job_uuid ?? (await claimViaPolling());

    if (!renderJobUuid) {
      await new Promise((resolve) => setTimeout(resolve, config.pollIntervalMs));
      continue;
    }

    console.log(`[worker] Picked up render job ${renderJobUuid}`);
    await handleJob(renderJobUuid);
  }
}

function startHealthServer(): void {
  const server = http.createServer((req, res) => {
    if (req.url === "/health" || req.url === "/") {
      const body = JSON.stringify({
        status: "ok",
        service: "colibri-video-engine",
        worker_id: config.workerId,
        started_at: startedAt,
        in_flight: inFlight.size,
        uptime_seconds: Math.floor(process.uptime()),
      });
      res.writeHead(200, { "Content-Type": "application/json" });
      res.end(body);
    } else {
      res.writeHead(404, { "Content-Type": "application/json" });
      res.end(JSON.stringify({ error: "Not found" }));
    }
  });

  server.listen(config.healthPort, () => {
    console.log(`[worker] Health server listening on port ${config.healthPort}`);
  });
}

async function main(): Promise<void> {
  assertWorkerConfig();
  startHealthServer();

  console.log(`[worker] Starting Colibri render worker (${config.workerId})`);  
  console.log(`[worker] API: ${config.apiUrl}`);
  console.log(`[worker] Storage: ${config.storageDriver}`);

  try {
    await queue.connect();
    console.log(`[worker] Connected to Redis queue "${config.renderQueue}"`);
  } catch (error) {
    console.warn("[worker] Redis connection failed; using API polling only.", error);
  }

  await loop();
}

main().catch((error) => {
  console.error("[worker] Fatal error", error);
  process.exit(1);
});
