import { NextRequest, NextResponse } from "next/server";
import fs from "node:fs";
import path from "node:path";
import { ApiError, requirePageRole } from "@/lib/auth";
import { handleApiError } from "@/lib/api-helpers";
import { ensureProjectRoot } from "@/lib/paths";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

function getBackupRoot() {
  const databaseUrl = process.env.DATABASE_URL?.trim();
  if (!databaseUrl?.startsWith("file:")) {
    throw new ApiError("تعذر تحديد مسار قاعدة البيانات للنسخ الاحتياطية", 500);
  }

  let databasePath = databaseUrl.slice("file:".length).split("?")[0];
  try { databasePath = decodeURIComponent(databasePath); } catch { /* احتفظ بالمسار كما هو */ }
  const root = ensureProjectRoot();
  databasePath = path.isAbsolute(databasePath) ? databasePath : path.resolve(root, databasePath);
  return path.join(path.dirname(databasePath), "backups", path.basename(root));
}

export async function GET(req: NextRequest) {
  try {
    await requirePageRole("settings", "ADMIN");
    const backupRoot = getBackupRoot();
    const downloadStamp = req.nextUrl.searchParams.get("download");

    if (downloadStamp) {
      if (!/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z$/.test(downloadStamp)) {
        throw new ApiError("معرّف النسخة الاحتياطية غير صالح", 400);
      }
      const folder = path.join(backupRoot, downloadStamp);
      const infoPath = path.join(folder, "backup-info.json");
      if (!fs.existsSync(infoPath)) throw new ApiError("لم نعثر على هذه النسخة الاحتياطية", 404);

      const info = JSON.parse(fs.readFileSync(infoPath, "utf8")) as { databaseFile?: string };
      const fileName = path.basename(info.databaseFile || "custom.db");
      const databasePath = path.join(folder, fileName);
      if (!fs.existsSync(databasePath) || !fs.statSync(databasePath).isFile()) {
        throw new ApiError("ملف قاعدة البيانات غير موجود داخل النسخة", 404);
      }

      const bytes = new Uint8Array(fs.readFileSync(databasePath));
      return new NextResponse(bytes, {
        headers: {
          "Content-Type": "application/vnd.sqlite3",
          "Content-Length": String(bytes.byteLength),
          "Content-Disposition": `attachment; filename="${fileName.replace(/"/g, "")}"`,
          "Cache-Control": "private, no-store",
        },
      });
    }

    if (!fs.existsSync(backupRoot)) return NextResponse.json({ backups: [] });
    const backups = fs.readdirSync(backupRoot, { withFileTypes: true })
      .filter((entry) => entry.isDirectory() && /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z$/.test(entry.name))
      .map((entry) => {
        try {
          const folder = path.join(backupRoot, entry.name);
          const info = JSON.parse(fs.readFileSync(path.join(folder, "backup-info.json"), "utf8")) as {
            createdAt?: string; fromVersion?: string; toVersion?: string; databaseFile?: string; databaseBytes?: number;
          };
          return {
            id: entry.name,
            createdAt: info.createdAt ?? "",
            fromVersion: info.fromVersion ?? "",
            toVersion: info.toVersion ?? "",
            databaseFile: path.basename(info.databaseFile || "custom.db"),
            databaseBytes: Number(info.databaseBytes) || 0,
          };
        } catch {
          return null;
        }
      })
      .filter((entry): entry is NonNullable<typeof entry> => Boolean(entry))
      .sort((a, b) => b.id.localeCompare(a.id));

    return NextResponse.json({ backups });
  } catch (err) {
    return handleApiError(err);
  }
}
