import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { spawn } from "node:child_process";
import { NextResponse } from "next/server";

const PYTHON = process.env.PYTHON_EXECUTABLE || "python";
const PROJECT_ROOT = join(process.cwd(), "..");
const RUNTIME_DIR = join(process.cwd(), ".runtime-crosswords");

function runPython(requestPayload: unknown): Promise<string> {
  return new Promise((resolve, reject) => {
    const child = spawn(PYTHON, ["crossword_service.py"], {
      cwd: PROJECT_ROOT,
      stdio: ["pipe", "pipe", "pipe"],
    });

    let stdout = "";
    let stderr = "";

    child.stdout.on("data", (chunk) => {
      stdout += chunk.toString();
    });

    child.stderr.on("data", (chunk) => {
      stderr += chunk.toString();
    });

    child.on("error", (error) => {
      reject(error);
    });

    child.on("close", (code) => {
      if (code !== 0) {
        reject(new Error(stderr || `Python process exited with code ${code}`));
        return;
      }
      resolve(stdout);
    });

    child.stdin.write(JSON.stringify(requestPayload));
    child.stdin.end();
  });
}

export async function POST(request: Request) {
  try {
    const payload = await request.json();
    const stdout = await runPython(payload);
    const responsePayload = JSON.parse(stdout);

    await mkdir(RUNTIME_DIR, { recursive: true });
    const targetPath = join(RUNTIME_DIR, `${responsePayload.crossword_id}.json`);
    await writeFile(targetPath, JSON.stringify(responsePayload, null, 2), "utf-8");

    return NextResponse.json(responsePayload);
  } catch (error) {
    return NextResponse.json(
      {
        status: "error",
        message: error instanceof Error ? error.message : "Unknown error",
      },
      { status: 500 },
    );
  }
}
