// FILE: backend/src/routes/rfas.js
// RFAs list/get/create/update/delete — มาตรฐาน Bearer + requirePerm
import { Router } from "express";
import sql from "../db/index.js";
import { requirePerm } from "../middleware/requirePerm.js";

const r = Router();

const ALLOWED_SORT = new Map([
  ["updated_at", "updated_at"],
  ["due_date", "due_date"],
  ["created_at", "created_at"],
  ["id", "id"],
]);
function parseSort(sort = "updated_at:desc") {
  const [c, d] = String(sort).split(":");
  const col = ALLOWED_SORT.get(c) || "updated_at";
  const dir = (d || "desc").toLowerCase() === "asc" ? "ASC" : "DESC";
  return `\`${col}\` ${dir}`;
}
function paging({ page = 1, pageSize = 20 }) {
  const p = Math.max(1, Number(page) || 1);
  const ps = Math.min(200, Math.max(1, Number(pageSize) || 20));
  return { limit: ps, offset: (p - 1) * ps, page: p, pageSize: ps };
}

// LIST (PROJECT scope enforced: filter ด้วย principal)
r.get(
  "/",
  requirePerm("rfas.view", { projectParam: "project_id" }),
  async (req, res) => {
    const { q, status, overdue, sort, page, pageSize, project_id } = req.query;
    const orderBy = parseSort(sort);
    const { limit, offset, page: p, pageSize: ps } = paging({ page, pageSize });

    const P = req.principal;
    const cond = [];
    const params = [];

    if (!P.is_superadmin) {
      if (project_id) {
        const pid = Number(project_id);
        if (!P.inProject(pid))
          return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
        cond.push("r.project_id=?");
        params.push(pid);
      } else if (P.project_ids?.length) {
        cond.push(
          `r.project_id IN (${P.project_ids.map(() => "?").join(",")})`
        );
        params.push(...P.project_ids);
      }
    } else if (project_id) {
      cond.push("r.project_id=?");
      params.push(Number(project_id));
    }

    if (status) {
      cond.push("r.status=?");
      params.push(status);
    }
    if (q) {
      cond.push("(r.rfa_no LIKE ? OR r.title LIKE ? OR r.code LIKE ?)");
      params.push(`%${q}%`, `%${q}%`, `%${q}%`);
    }
    if (String(overdue) === "1") {
      cond.push(
        "r.due_date IS NOT NULL AND r.due_date < CURDATE() AND r.status NOT IN ('Closed','Approved')"
      );
    }
    const where = cond.length ? `WHERE ${cond.join(" AND ")}` : "";

    const [[{ cnt }]] = await sql.query(
      `SELECT COUNT(*) AS cnt FROM rfas r ${where}`,
      params
    );
    const [rows] = await sql.query(
      `SELECT r.id, r.code, r.rfa_no, r.title, r.status, r.discipline, r.due_date, r.updated_at, r.project_id
     FROM rfas r ${where} ORDER BY ${orderBy} LIMIT ? OFFSET ?`,
      [...params, limit, offset]
    );
    res.json({ data: rows, total: Number(cnt || 0), page: p, pageSize: ps });
  }
);

// GET ONE
r.get("/:id", requirePerm("rfas.view"), async (req, res) => {
  const id = Number(req.params.id);
  const [[row]] = await sql.query("SELECT * FROM rfas WHERE id=?", [id]);
  if (!row) return res.status(404).json({ error: "Not found" });
  const P = req.principal;
  if (!P.is_superadmin && !P.inProject(row.project_id))
    return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
  res.json(row);
});

// CREATE
r.post(
  "/",
  requirePerm("rfas.create", { projectParam: "project_id" }),
  async (req, res) => {
    const { org_id, project_id, rfa_no, title, status } = req.body || {};
    if (!project_id || !title)
      return res.status(400).json({ error: "project_id and title required" });
    const [rs] = await sql.query(
      `INSERT INTO rfas (org_id, project_id, rfa_no, title, status, created_by, created_at, updated_at)
     VALUES (?,?,?,?,?,?,NOW(),NOW())`,
      [
        org_id ?? null,
        project_id,
        rfa_no ?? null,
        title,
        status ?? "draft",
        req.principal.user_id,
      ]
    );
    res.status(201).json({ id: rs.insertId });
  }
);

// UPDATE (respond/edit)
r.patch("/:id", requirePerm("rfas.respond"), async (req, res) => {
  const id = Number(req.params.id);
  const [[row]] = await sql.query("SELECT * FROM rfas WHERE id=?", [id]);
  if (!row) return res.status(404).json({ error: "Not found" });
  const P = req.principal;
  if (!P.is_superadmin && !P.inProject(row.project_id))
    return res.status(403).json({ error: "FORBIDDEN_PROJECT" });

  const allowed = [
    "code",
    "rfa_no",
    "title",
    "discipline",
    "due_date",
    "description",
    "status",
    "owner_id",
  ];
  const patch = {};
  for (const k of allowed) if (k in req.body) patch[k] = req.body[k];
  if (!Object.keys(patch).length)
    return res.status(400).json({ error: "no fields to update" });

  const sets = Object.keys(patch).map((k) => `\`${k}\`=?`);
  await sql.query(
    `UPDATE rfas SET ${sets.join(", ")}, updated_at=NOW() WHERE id=?`,
    [...Object.values(patch), id]
  );
  res.json({ ok: 1, id });
});

// DELETE
r.delete("/:id", requirePerm("rfas.delete"), async (req, res) => {
  const id = Number(req.params.id);
  const [[row]] = await sql.query("SELECT project_id FROM rfas WHERE id=?", [
    id,
  ]);
  if (!row) return res.status(404).json({ error: "Not found" });
  const P = req.principal;
  if (!P.is_superadmin && !P.inProject(row.project_id))
    return res.status(403).json({ error: "FORBIDDEN_PROJECT" });
  await sql.query("DELETE FROM rfas WHERE id=?", [id]);
  res.json({ ok: 1 });
});

export default r;
