// FILE: backend/src/routes/files_extras.js
// NOTE: generic file actions – ผูกสิทธิ์ตามโมดูลปลายทาง และบังคับ ABAC จาก project_id ของเรคคอร์ด
import { Router } from "express";
import fs from "node:fs";
import sql from "../db/index.js";

const r = Router();

async function projectForFile(rec) {
  // โปรเจ็คของไฟล์อิงโมดูล/ตารางอ้างอิง
  switch (rec.module) {
    case "rfa": {
      const [[row]] = await sql.query(
        "SELECT project_id FROM rfas WHERE id=?",
        [rec.ref_id]
      );
      return row?.project_id || null;
    }
    case "correspondence": {
      const [[row]] = await sql.query(
        "SELECT project_id FROM correspondences WHERE id=?",
        [rec.ref_id]
      );
      return row?.project_id || null;
    }
    case "drawing": {
      const [[row]] = await sql.query(
        "SELECT project_id FROM drawings WHERE id=?",
        [rec.ref_id]
      );
      return row?.project_id || null;
    }
    case "document": {
      const [[row]] = await sql.query(
        "SELECT project_id FROM documents WHERE document_id=?",
        [rec.ref_id]
      );
      return row?.project_id || null;
    }
    case "transmittal": {
      const [[row]] = await sql.query(
        "SELECT project_id FROM transmittals WHERE id=?",
        [rec.ref_id]
      );
      return row?.project_id || null;
    }
    default:
      return null;
  }
}

function permForFile(rec, action /* 'read'|'update'|'delete' */) {
  // map เป็น permission ของโมดูลจริง
  const m = rec.module;
  if (m === "document")
    return action === "read" ? "documents.view" : "documents.manage";
  if (m === "drawing")
    return action === "read"
      ? "drawings.view"
      : action === "delete"
      ? "drawings.delete"
      : "drawings.upload";
  if (m === "correspondence")
    return action === "read" ? "corr.view" : "corr.manage";
  if (m === "rfa") return action === "read" ? "rfas.view" : "rfas.respond";
  if (m === "transmittal") return "transmittals.manage";
  return "documents.manage"; // fallback
}

// HEAD meta
r.head("/files/:file_id", async (req, res) => {
  const id = Number(req.params.file_id);
  const [[rec]] = await sql.query("SELECT * FROM files WHERE file_id=?", [id]);
  if (!rec) return res.status(404).end();
  res.setHeader("Content-Type", rec.mime || "application/octet-stream");
  res.setHeader("Content-Length", String(rec.size || 0));
  res.status(200).end();
});

// DELETE
r.delete("/files/:file_id", async (req, res) => {
  const id = Number(req.params.file_id);
  const [[rec]] = await sql.query("SELECT * FROM files WHERE file_id=?", [id]);
  if (!rec) return res.status(404).json({ error: "Not found" });

  const p = req.principal;
  if (!p) return res.status(401).json({ error: "Unauthenticated" });

  const pid = await projectForFile(rec);
  if (!p.is_superadmin) {
    if (!pid || !p.inProject(pid))
      return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
    const need = permForFile(rec, "delete");
    if (!p.can?.(need))
      return res.status(403).json({ error: "FORBIDDEN", need });
  }

  try {
    if (rec.disk_path) fs.unlinkSync(rec.disk_path);
  } catch {}
  await sql.query("DELETE FROM files WHERE file_id=?", [id]);
  res.json({ ok: true });
});

// RENAME (meta only)
r.post("/files/:file_id/rename", async (req, res) => {
  const id = Number(req.params.file_id);
  const [[rec]] = await sql.query("SELECT * FROM files WHERE file_id=?", [id]);
  if (!rec) return res.status(404).json({ error: "Not found" });

  const p = req.principal;
  if (!p) return res.status(401).json({ error: "Unauthenticated" });

  const pid = await projectForFile(rec);
  if (!p.is_superadmin) {
    if (!pid || !p.inProject(pid))
      return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
    const need = permForFile(rec, "update");
    if (!p.can?.(need))
      return res.status(403).json({ error: "FORBIDDEN", need });
  }

  const { orig_name } = req.body || {};
  if (!orig_name) return res.status(400).json({ error: "orig_name required" });
  await sql.query("UPDATE files SET orig_name=? WHERE file_id=?", [
    orig_name,
    id,
  ]);
  res.json({ ok: true });
});

// refresh signed download URL – ปกติใช้ signed URL service ภายนอก; ที่นี่คืน URL ภายในเป็นตัวอย่าง
r.post("/files/:file_id/refresh-url", async (req, res) => {
  const id = Number(req.params.file_id);
  const [[rec]] = await sql.query("SELECT * FROM files WHERE file_id=?", [id]);
  if (!rec) return res.status(404).json({ error: "Not found" });

  const p = req.principal;
  if (!p) return res.status(401).json({ error: "Unauthenticated" });

  const pid = await projectForFile(rec);
  if (!p.is_superadmin) {
    if (!pid || !p.inProject(pid))
      return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
    const need = permForFile(rec, "read");
    if (!p.can?.(need))
      return res.status(403).json({ error: "FORBIDDEN", need });
  }

  const expSec = Number(process.env.FILE_URL_EXPIRES || 600);
  const download_url = `/api/files/${rec.file_id}?token=internal-placeholder&exp=${expSec}`;
  res.json({ download_url, expires_in: expSec });
});

export default r;
