const express = require("express");
const {
  acceptPrintJob,
  getJob,
  replayJob,
  metricsText,
  getHealthExtras,
} = require("./print-queue");
const {
  requirePrintApiToken,
  authorizeMetrics,
  authorizeReplay,
  requireSignatureIfPresent,
} = require("./auth");

function createPrintRouter({ getPrinterHealth, serviceVersion, startTime }) {
  const router = express.Router();

  router.get("/health", (req, res) => {
    const printer = getPrinterHealth ? getPrinterHealth() : {};
    res.json({
      ok: true,
      status: "OK",
      service: "siraya-printer",
      version: serviceVersion,
      timestamp: new Date().toISOString(),
      uptimeSec: startTime
        ? Math.floor((Date.now() - startTime) / 1000)
        : 0,
      business: process.env.BUSINESS_NAME || "SIRAYA",
      ...getHealthExtras(),
      ...printer,
    });
  });

  router.get("/metrics", (req, res) => {
    if (!authorizeMetrics(req)) {
      return res.status(401).type("text/plain").send("unauthorized");
    }
    res.status(200).type("text/plain; version=0.0.4").send(metricsText());
  });

  router.post(
    "/v1/print/jobs",
    requirePrintApiToken,
    requireSignatureIfPresent,
    (req, res) => {
      try {
        const out = acceptPrintJob(req.body, { legacy: false });
        const code = out.deduped ? 200 : 202;
        res.status(code).json(out);
      } catch (e) {
        res.status(e.status || 400).json({ error: String(e.message || e) });
      }
    },
  );

  router.get("/v1/print/jobs/:id", (req, res) => {
    const j = getJob(req.params.id);
    if (!j) return res.status(404).json({ error: "NOT_FOUND" });
    res.json({
      printJobId: j.printJobId,
      state: j.state,
      attempts: j.attempts,
      lastError: j.lastError || null,
      updatedAt: j.updatedAt,
    });
  });

  router.post("/v1/print/jobs/:id/replay", requirePrintApiToken, (req, res) => {
    if (!authorizeReplay(req)) {
      return res.status(401).json({ error: "REPLAY_AUTH_REQUIRED" });
    }
    try {
      const force =
        String(req.query.force || "") === "1" ||
        String(req.query.force || "") === "true";
      const out = replayJob(req.params.id, { force });
      if (!out) return res.status(404).json({ error: "NOT_FOUND" });
      res.status(202).json(out);
    } catch (e) {
      res.status(e.status || 400).json({ error: String(e.message || e) });
    }
  });

  /** Legacy + web UI: enqueue then return (POS v1 preferred for polling). */
  router.post("/print", requirePrintApiToken, requireSignatureIfPresent, (req, res) => {
    try {
      const out = acceptPrintJob(req.body, { legacy: true });
      res.status(200).json({ ok: true, success: true, ...out });
    } catch (e) {
      res.status(e.status || 400).json({
        ok: false,
        success: false,
        error: String(e.message || e),
      });
    }
  });

  return router;
}

module.exports = { createPrintRouter };
