import schedule from "node-schedule";
import { spawn } from "child_process";
import { existsSync, mkdirSync } from "fs";
import { join } from "path";
import { getAllStreams, getStreamProcess } from "$lib/server/streaming.js";

const TIMELAPSE_OUTPUT_PATH =
	process.env.TIMELAPSE_OUTPUT_PATH || "./timelapse";
const CAPTURE_INTERVAL = "0 * * * *"; // Every hour at minute 0

let captureJob: any = null;
let initialized = false;

function ensureOutputDirectory() {
	if (!existsSync(TIMELAPSE_OUTPUT_PATH)) {
		mkdirSync(TIMELAPSE_OUTPUT_PATH, { recursive: true });
	}
}

function captureTimelapseFrame() {
	const streams = getAllStreams();

	streams.forEach((streamInfo) => {
		const stream = getStreamProcess(streamInfo.streamId);
		if (!stream || !stream.process || !stream.process.stdout) {
			console.error(
				`[Timelapse] Stream ${streamInfo.streamId} not available for capture`,
			);
			return;
		}

		const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
		const filename = `${streamInfo.streamId}_${timestamp}.jpg`;
		const outputPath = join(TIMELAPSE_OUTPUT_PATH, filename);

		const ffmpegArgs = [
			"-rtsp_transport",
			"tcp",
			"-i",
			streamInfo.rtspUrl,
			"-vframes",
			"1",
			"-q:v",
			"2",
			outputPath,
		];

		const ffmpegProcess = spawn("ffmpeg", ffmpegArgs);

		ffmpegProcess.on("error", (err: Error) => {
			console.error(
				`[Timelapse] FFmpeg error for ${streamInfo.streamId}:`,
				err,
			);
		});

		ffmpegProcess.on("close", (code: number | null) => {
			if (code === 0) {
				console.log(
					`[Timelapse] Captured frame for ${streamInfo.streamId}: ${filename}`,
				);
			} else {
				console.error(
					`[Timelapse] FFmpeg exited with code ${code} for ${streamInfo.streamId}`,
				);
			}
		});
	});
}

function initializeTimelapse() {
	if (initialized) {
		return;
	}

	ensureOutputDirectory();
	console.log(`[Timelapse] Output directory: ${TIMELAPSE_OUTPUT_PATH}`);
	console.log("[Timelapse] Starting hourly capture job...");

	captureJob = schedule.scheduleJob(CAPTURE_INTERVAL, () => {
		console.log("[Timelapse] Running hourly capture job...");
		captureTimelapseFrame();
	});

	initialized = true;
	console.log("[Timelapse] Hourly capture job initialized");
}

export async function handle({ event, resolve }) {
	// Initialize timelapse on first request
	if (!initialized) {
		initializeTimelapse();
	}

	return resolve(event);
}

// Cleanup on shutdown
process.on("exit", () => {
	if (captureJob) {
		captureJob.cancel();
		console.log("[Timelapse] Capture job cancelled");
	}
});
