import { NextRequest, NextResponse } from "next/server";
import { readFileSync, statSync } from "node:fs";
import { resolve, extname } from "node:path";
import { getDb } from "@/lib/db";

const MAX_FILE_SIZE =
  Number.parseInt(process.env.MAX_CODE_FILE_SIZE_BYTES || "", 10) || 5 * 1024 * 1024; // 5MB default

const LANG_MAP: Record<string, string> = {
  ".java": "java",
  ".xml": "xml",
  ".properties": "properties",
  ".yml": "yaml",
  ".yaml": "yaml",
  ".json": "json",
  ".ts": "typescript",
  ".tsx": "typescript",
  ".js": "javascript",
  ".jsx": "javascript",
  ".md": "markdown",
  ".css": "css",
  ".html": "html",
  ".py": "python",
  ".sh": "shell",
  ".sql": "sql",
  ".txt": "text",
  ".gradle": "groovy",
  ".kt": "kotlin",
  ".scala": "scala",
};

function sanitizePath(sourceRoot: string, reqPath: string): string | null {
  if (reqPath.includes("..") || reqPath.startsWith("/")) return null;
  const full = resolve(sourceRoot, reqPath);
  if (!full.startsWith(sourceRoot)) return null;
  return full;
}

function detectLanguage(filePath: string): string {
  const ext = extname(filePath).toLowerCase();
  return LANG_MAP[ext] || "text";
}

export async function POST(request: NextRequest) {
  try {
    const { repository_id, path: reqPath } = await request.json();

    if (!repository_id || typeof repository_id !== "string") {
      return NextResponse.json({ error: "repository_id is required" }, { status: 400 });
    }

    if (!reqPath || typeof reqPath !== "string") {
      return NextResponse.json({ error: "Path is required" }, { status: 400 });
    }

    const db = await getDb();
    const { rows } = await db.query(
      "SELECT source_path FROM repositories WHERE id = $1",
      [repository_id],
    );
    if (rows.length === 0) {
      return NextResponse.json({ error: "Repository not found" }, { status: 404 });
    }

    const reposBase = process.env.REPOS_PATH ? resolve(process.env.REPOS_PATH, "..") : process.cwd();
    const sourceRoot = resolve(reposBase, rows[0].source_path);
    const fullPath = sanitizePath(sourceRoot, reqPath);
    if (!fullPath) {
      return NextResponse.json({ error: "Invalid path" }, { status: 400 });
    }

    const stat = statSync(fullPath, { throwIfNoEntry: false });
    if (!stat || !stat.isFile()) {
      return NextResponse.json({ error: "Not a file" }, { status: 400 });
    }

    if (stat.size > MAX_FILE_SIZE) {
      return NextResponse.json(
        {
          error: `File too large (${(stat.size / 1024 / 1024).toFixed(1)}MB, max ${(MAX_FILE_SIZE / 1024 / 1024).toFixed(1)}MB)`,
        },
        { status: 400 },
      );
    }

    const content = readFileSync(fullPath, "utf-8");
    const language = detectLanguage(fullPath);

    return NextResponse.json({ path: reqPath, content, language });
  } catch (err) {
    const msg = err instanceof Error ? err.message : "Unknown error";
    return NextResponse.json({ error: msg }, { status: 500 });
  }
}
