import "./env.js";
import express from "express";
import path from "path";
import { fileURLToPath } from "url";
import cors from "cors";
import zoosRouter from "./routes/zoos.js";
import salesRouter from "./routes/sales.js";
import { createAccount } from "./db.js";
import { startBotTickInterval } from "./bot-tick.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const webDir = path.join(__dirname, "..", "web");

const app = express();
app.use(cors({ origin: true, credentials: true }));

app.use(
  "/api/zoos",
  express.raw({ type: "*/*", limit: "2mb" }),
  (req, res, next) => {
    req.bodyRaw =
      req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : "";
    try {
      req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {};
    } catch {
      req.body = {};
    }
    next();
  },
  zoosRouter
);

app.use(
  "/api/sales",
  express.raw({ type: "*/*", limit: "2mb" }),
  (req, res, next) => {
    req.bodyRaw =
      req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : "";
    try {
      req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {};
    } catch {
      req.body = {};
    }
    next();
  },
  salesRouter
);

app.use(
  "/api/auth",
  express.raw({ type: "*/*", limit: "10kb" }),
  (req, res, next) => {
    req.bodyRaw =
      req.body && Buffer.isBuffer(req.body) ? req.body.toString("utf8") : "";
    try {
      req.body = req.bodyRaw ? JSON.parse(req.bodyRaw) : {};
    } catch {
      req.body = {};
    }
    next();
  }
);
app.post("/api/auth/register", (req, res, next) => {
  const publicKey = req.headers["x-public-key"];
  const pseudo = req.body?.pseudo?.trim();
  if (!publicKey || !pseudo || pseudo.length < 2) {
    res.status(400).json({
      error: "pseudo required (min 2 chars) and X-Public-Key",
    });
    return;
  }
  createAccount(publicKey, pseudo)
    .then((account) => {
      res.status(201).json({ id: account.id, pseudo: account.pseudo });
    })
    .catch((err) => {
      console.error("[auth/register]", err?.message ?? err);
      if (err.code === "23505") {
        res.status(409).json({ error: "pseudo or publicKey already used" });
        return;
      }
      next(err);
    });
});

app.get("/api/health", (req, res) => {
  res.json({ ok: true });
});

app.use(express.static(webDir));
app.get("*", (req, res) => {
  res.sendFile(path.join(webDir, "index.html"));
});

app.use((err, _req, res, _next) => {
  console.error("[api]", err?.message ?? err);
  res.status(500).json({ error: "Internal server error" });
});

const port = Number(process.env.PORT) || 3000;
app.listen(port, () => {
  console.warn(`builazoo API listening on port ${port}`);
  startBotTickInterval();
});
