const express = require("express");
const fs = require("fs");
const path = require("path");
const {
  getBrandingDir,
  findLogoPath,
  saveLogoFromBuffer,
  clearLogoCache,
} = require("./logo-escpos");
const { buildQrPngBuffer, buildQrRowPngBuffer } = require("./qr-escpos");
const { ensureDir } = require("./paths");
const { loadTemplateById, saveTemplateById } = require("./template-engine-v2");

function syncLogoToStandardTemplate(logoPath) {
  const tpl = loadTemplateById("standard-receipt");
  if (!tpl) return null;
  tpl.branding = tpl.branding || {};
  tpl.branding.logoPath = logoPath;
  tpl.conditionals = tpl.conditionals || {};
  tpl.conditionals.showLogo = true;
  tpl.business = tpl.business || {};
  tpl.business.showLogo = true;
  return saveTemplateById(tpl);
}

function createBrandingRouter() {
  const router = express.Router();

  router.get("/api/branding/logo/status", async (req, res) => {
    const { getLogoDiagnostics } = require("./logo-escpos");
    res.json(await getLogoDiagnostics());
  });

  router.get("/api/branding/logo", (req, res) => {
    const logoPath = findLogoPath();
    if (!logoPath) {
      return res.status(404).json({ error: "NO_LOGO" });
    }
    res.set("Cache-Control", "no-store");
    res.sendFile(logoPath);
  });

  router.post("/api/branding/logo", async (req, res) => {
    try {
      const body = req.body || {};
      let buffer;
      if (body.data && typeof body.data === "string") {
        const match = body.data.match(/^data:image\/(\w+);base64,/);
        const raw = match ? body.data.slice(match[0].length) : body.data;
        buffer = Buffer.from(raw, "base64");
      } else {
        return res.status(400).json({ error: "Missing base64 data" });
      }

      if (!buffer.length) {
        return res.status(400).json({ error: "Empty image" });
      }

      const logoPath = await saveLogoFromBuffer(buffer);
      syncLogoToStandardTemplate(logoPath);
      const { getLogoDiagnostics } = require("./logo-escpos");
      const diag = await getLogoDiagnostics();
      res.json({
        ok: true,
        logoPath,
        url: "/api/branding/logo",
        printReady: diag.printReady,
        jimpInstalled: diag.jimpInstalled,
        escposBytes: diag.escposBytes,
      });
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  router.delete("/api/branding/logo", (req, res) => {
    try {
      ensureDir(getBrandingDir());
      for (const file of fs.readdirSync(getBrandingDir())) {
        if (file.startsWith("logo.")) {
          fs.unlinkSync(path.join(getBrandingDir(), file));
        }
      }
      clearLogoCache();
      const tpl = loadTemplateById("standard-receipt");
      if (tpl) {
        tpl.branding = tpl.branding || {};
        tpl.branding.logoPath = "";
        tpl.conditionals = tpl.conditionals || {};
        tpl.conditionals.showLogo = false;
        saveTemplateById(tpl);
      }
      res.json({ ok: true });
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  router.get("/api/branding/qr/image", async (req, res) => {
    try {
      const url = String(req.query.url || req.query.data || "").trim();
      if (!url) return res.status(400).json({ error: "Missing url" });
      const paperWidth = parseInt(String(req.query.paperWidth || "32"), 10) || 32;
      const png = await buildQrPngBuffer(url, paperWidth);
      if (!png) return res.status(503).json({ error: "QR generation unavailable" });
      res.set("Content-Type", "image/png");
      res.set("Cache-Control", "no-store");
      res.send(png);
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  router.get("/api/branding/qr/row", async (req, res) => {
    try {
      const raw = String(req.query.urls || req.query.url || "").trim();
      if (!raw) return res.status(400).json({ error: "Missing urls" });
      const urls = raw.split(",").map((s) => s.trim()).filter(Boolean);
      if (!urls.length) return res.status(400).json({ error: "Missing urls" });
      const paperWidth = parseInt(String(req.query.paperWidth || "32"), 10) || 32;
      const png = await buildQrRowPngBuffer(
        urls.map((url) => ({ url })),
        paperWidth,
      );
      if (!png) return res.status(503).json({ error: "QR row generation unavailable" });
      res.set("Content-Type", "image/png");
      res.set("Cache-Control", "no-store");
      res.send(png);
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  router.put("/api/branding/qr", (req, res) => {
    try {
      const { linkUrl, links, enabled, templateId = "standard-receipt" } = req.body || {};
      const tpl = loadTemplateById(templateId);
      if (!tpl) return res.status(404).json({ error: "TEMPLATE_NOT_FOUND" });
      tpl.branding = tpl.branding || {};
      tpl.branding.qrCode = tpl.branding.qrCode || {};
      if (Array.isArray(links)) {
        tpl.branding.qrCode.links = links
          .map((entry) =>
            typeof entry === "string"
              ? { url: entry.trim() }
              : { url: String(entry?.url || "").trim() },
          )
          .filter((entry) => entry.url);
        tpl.branding.qrCode.linkUrl = tpl.branding.qrCode.links[0]?.url || "";
      } else if (linkUrl != null) {
        tpl.branding.qrCode.linkUrl = String(linkUrl).trim();
        tpl.branding.qrCode.links = tpl.branding.qrCode.linkUrl
          ? [{ url: tpl.branding.qrCode.linkUrl }]
          : [];
      }
      if (enabled != null) tpl.branding.qrCode.enabled = Boolean(enabled);
      tpl.conditionals = tpl.conditionals || {};
      tpl.conditionals.showQrCode = Boolean(tpl.branding.qrCode.enabled);
      const saved = saveTemplateById(tpl);
      res.json(saved);
    } catch (e) {
      res.status(400).json({ error: String(e.message || e) });
    }
  });

  return router;
}

module.exports = { createBrandingRouter };
