import { Router, Request, Response } from "express";
import { spawn } from "child_process";
import path from "path";
import fs from "fs";
import archiver from "archiver";
import { getOrCreateApiKey } from "../services/networkSyncConfigService";

const router = Router();

const UPLOADS_DIR = path.resolve(process.cwd(), "uploads");

function isLanIp(ip: string): boolean {
  return (
    /^127\./.test(ip) ||
    /^10\./.test(ip) ||
    /^192\.168\./.test(ip) ||
    /^172\.(1[6-9]|2\d|3[01])\./.test(ip)
  );
}

function checkAccess(req: Request, res: Response): boolean {
  // Only allow requests from the local network
  const ip =
    (req.headers["x-real-ip"] as string) ||
    (req.headers["x-forwarded-for"] as string)?.split(",")[0].trim() ||
    req.socket.remoteAddress ||
    "";
  if (!isLanIp(ip)) {
    res.status(403).json({ error: "Access restricted to local network" });
    return false;
  }

  const providedKey = req.headers["x-network-backup-key"] as string | undefined;
  if (!providedKey) {
    res.status(401).json({ error: "Missing X-Network-Backup-Key header" });
    return false;
  }
  const storedKey = getOrCreateApiKey();
  if (providedKey !== storedKey) {
    res.status(401).json({ error: "Invalid API key" });
    return false;
  }
  return true;
}

// GET /api/database-management/network-backup
router.get("/network-backup", async (req: Request, res: Response): Promise<any> => {
  if (!checkAccess(req, res)) return;

  const pg = spawn(
    "pg_dump",
    [
      "--no-acl", "--no-owner",
      "-h", process.env.DB_HOST || "localhost",
      "-U", process.env.DB_USER || "postgres",
      process.env.DB_NAME || "dental_db",
    ],
    { env: { ...process.env, PGPASSWORD: process.env.DB_PASSWORD } }
  );

  res.setHeader("Content-Type", "application/octet-stream");
  res.setHeader(
    "Content-Disposition",
    `attachment; filename="network_backup_${Date.now()}.sql"`
  );

  pg.stdout.pipe(res);

  let stderr = "";
  pg.stderr.on("data", (d) => (stderr += d.toString()));
  pg.on("error", (err) => {
    if (!res.headersSent)
      res.status(500).json({ error: "pg_dump failed", details: err.message });
  });
  pg.on("close", (code) => {
    if (code !== 0) console.error("pg_dump for network backup failed:", stderr);
  });
});

// GET /api/database-management/network-backup-files
router.get("/network-backup-files", (req: Request, res: Response): any => {
  if (!checkAccess(req, res)) return;

  if (!fs.existsSync(UPLOADS_DIR)) {
    return res.status(200).end();
  }

  res.setHeader("Content-Type", "application/zip");
  res.setHeader("Content-Disposition", `attachment; filename="network_uploads_${Date.now()}.zip"`);

  const archive = archiver("zip", { zlib: { level: 6 } });
  archive.on("error", (err) => {
    if (!res.headersSent) res.status(500).json({ error: "Failed to create archive", details: err.message });
  });

  archive.pipe(res);
  archive.directory(UPLOADS_DIR, false);
  archive.finalize();
});

export default router;
