import { NextResponse } from "next/server";
import { promisify } from "util";
import { exec } from "child_process";
import fs from "fs";
import path from "path";

const execPromise = promisify(exec);

export async function GET(request: Request) {
  try {
    const { searchParams } = new URL(request.url);
    const action = searchParams.get("action");
    const rootPath = searchParams.get("root");
    const file = searchParams.get("file");

    const targetRoot = ((rootPath && fs.existsSync(rootPath)) ? rootPath : process.cwd()).replace(/\\/g, "/");

    // Check if it's a git repo
    try {
      await execPromise("git rev-parse --is-inside-work-tree", { cwd: targetRoot });
    } catch {
      return NextResponse.json({ success: true, isGit: false, files: [] });
    }

    if (action === "status") {
      const { stdout } = await execPromise("git status --porcelain", { cwd: targetRoot });
      const lines = stdout.split(/\r?\n/).filter(Boolean);
      const files = lines.map(line => {
        // porcelain format: XY path or XY "path"
        const status = line.substring(0, 2);
        let relativePath = line.substring(3).trim();
        // Remove quotes if git quoted the path
        if (relativePath.startsWith('"') && relativePath.endsWith('"')) {
          relativePath = relativePath.slice(1, -1);
        }
        const absolutePath = path.join(targetRoot, relativePath).replace(/\\/g, "/");
        return {
          status: status.trim(),
          relativePath,
          absolutePath,
          name: path.basename(relativePath)
        };
      });

      return NextResponse.json({ success: true, isGit: true, files });
    }

    if (action === "diff") {
      if (!file) {
        return NextResponse.json({ error: "Missing file parameter" }, { status: 400 });
      }

      const absolutePath = path.resolve(targetRoot, file).replace(/\\/g, "/");
      if (!fs.existsSync(absolutePath)) {
        return NextResponse.json({ error: "File not found" }, { status: 404 });
      }

      // Check status to see if it is untracked
      const { stdout: statusOut } = await execPromise("git status --porcelain -- " + JSON.stringify(file), { cwd: targetRoot });
      const isUntracked = statusOut.startsWith("??");

      if (isUntracked) {
        const fileContent = fs.readFileSync(absolutePath, "utf8");
        const diffLines = fileContent.split(/\r?\n/).map(l => "+" + l).join("\n");
        return NextResponse.json({ success: true, diff: diffLines });
      } else {
        try {
          const { stdout: diffOut } = await execPromise(`git diff --no-color -- ${JSON.stringify(file)}`, { cwd: targetRoot });
          return NextResponse.json({ success: true, diff: diffOut });
        } catch {
          return NextResponse.json({ success: true, diff: `Binary file or diff unavailable.` });
        }
      }
    }

    return NextResponse.json({ error: "Invalid action" }, { status: 400 });
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : "Unknown error";
    return NextResponse.json({ error: errorMessage }, { status: 500 });
  }
}
