const express = require("express");
const fs = require("fs");
const path = require("path");
const {
  getPublicSettings,
  updateSettings,
  initSettings,
  loadSettings,
} = require("./settings-store");
const { isPortAvailable, validatePort, findAvailablePort } = require("./port-utils");
const { getLogsDir, getSirayaDataRoot } = require("./paths");
const { listJobs, replayJob } = require("./print-queue");

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

  router.get("/settings", (req, res) => {
    res.json(getPublicSettings());
  });

  router.put("/settings", async (req, res) => {
    try {
      const body = req.body || {};
      if (body.port != null && !body.skipPortCheck) {
        const host = body.host || loadSettings().host || "127.0.0.1";
        const port = validatePort(body.port);
        const current = loadSettings().port;
        if (port !== current) {
          const ok = await isPortAvailable(host, port);
          if (!ok) {
            return res.status(409).json({ error: "PORT_IN_USE", port });
          }
        }
      }
      const updated = updateSettings(body);
      res.json({
        ...getPublicSettings(),
        restartRequired: body.port != null && body.port !== loadSettings().port,
        settings: updated,
      });
    } catch (e) {
      res.status(e.status || 400).json({ error: String(e.message || e) });
    }
  });

  router.post("/settings/regenerate-api-key", (req, res) => {
    const { regenerateApiKey, getApiToken } = require("./settings-store");
    const key = regenerateApiKey();
    res.json({
      ok: true,
      apiKey: key,
      serviceUrl: getPublicSettings().serviceUrl,
    });
  });

  router.get("/settings/api-key", (req, res) => {
    const { getApiToken } = require("./settings-store");
    res.json({
      apiKey: getApiToken(),
      serviceUrl: getPublicSettings().serviceUrl,
    });
  });

  router.get("/print/history", (req, res) => {
    const limit = Math.min(parseInt(req.query.limit || "50", 10) || 50, 200);
    const offset = parseInt(req.query.offset || "0", 10) || 0;
    res.json(listJobs({ limit, offset }));
  });

  router.post("/print/history/:id/retry", (req, res) => {
    try {
      const out = replayJob(req.params.id, { force: true });
      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) });
    }
  });

  router.get("/logs/json", (req, res) => {
    const logDir = getLogsDir();
    const files = [];
    try {
      if (fs.existsSync(logDir)) {
        for (const file of fs.readdirSync(logDir)) {
          if (!file.endsWith(".log")) continue;
          const content = fs.readFileSync(path.join(logDir, file), "utf8");
          files.push({ name: file, content: content.slice(-50000) });
        }
      }
    } catch {
      /* ignore */
    }
    res.json({ files, dataDir: getSirayaDataRoot() });
  });

  router.get("/status", (req, res) => {
    const printer = getPrinterHealth ? getPrinterHealth() : {};
    res.json({
      ok: true,
      service: "siraya-printer",
      version: serviceVersion,
      uptimeSec: Math.floor((Date.now() - startTime) / 1000),
      ...getPublicSettings(),
      ...printer,
    });
  });

  router.post("/printers/test", (req, res) => {
    res.json({
      ok: true,
      message: "Printer test via POST /print recommended",
    });
  });

  router.get("/updates/versions", (req, res) => {
    try {
      const vm = require("./version-manager");
      res.json({
        current: vm.getCurrentVersionPointer(),
        installed: vm.listInstalledVersions(),
      });
    } catch (e) {
      res.json({ current: null, installed: [], error: e.message });
    }
  });

  router.post("/updates/rollback", (req, res) => {
    try {
      const vm = require("./version-manager");
      const prev = vm.rollbackToPrevious();
      res.json({ ok: true, version: prev });
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  return router;
}

module.exports = { createSettingsRouter };
