import express from "express";
import helmet from "helmet";
import morgan from "morgan";
import dotenv from "dotenv";
import apiRouter from "./routes/index.js";
import { notFound, errorHandler } from "./middlewares/errorHandler.js";

dotenv.config();

const app = express();

/** JSON APIs should not use ETag/304 — clients expect a fresh body after mutations. */
const apiApp = express();
apiApp.set("etag", false);
apiApp.use((req, res, next) => {
  res.set("Cache-Control", "no-store, no-cache, must-revalidate");
  res.set("Pragma", "no-cache");
  next();
});
apiApp.use(apiRouter);

app.use(
  helmet({
    crossOriginResourcePolicy: { policy: "cross-origin" }
  })
);
const jsonBodyParser = express.json({ limit: "50mb" });
app.use((req, res, next) => {
  const contentType = String(req.headers["content-type"] || "").toLowerCase();
  if (contentType.includes("multipart/form-data")) {
    return next();
  }
  if (req.method === "GET" || req.method === "HEAD" || req.method === "OPTIONS") {
    return next();
  }
  return jsonBodyParser(req, res, next);
});
app.use(express.urlencoded({ extended: true, limit: "50mb" }));

const allowedOrigins = (
  process.env.ALLOWED_ORIGINS ||
  [
    "http://127.0.0.1:5500",
    "http://localhost:5500",
    "http://localhost:5173",
    "http://127.0.0.1:5173",
    "http://localhost:5174",
    "http://127.0.0.1:5174"
  ].join(",")
)
  .split(",")
  .map((origin) => origin.trim())
  .filter(Boolean);

// CORS: allow configured frontend origins
app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (origin && allowedOrigins.includes(origin)) {
    res.header("Access-Control-Allow-Origin", origin);
  }

  res.header("Vary", "Origin");
  res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.header("Access-Control-Allow-Credentials", "true");
  if (req.method === "OPTIONS") {
    return res.sendStatus(204);
  }
  next();
});

if (process.env.NODE_ENV !== "test") {
  app.use(morgan("dev"));
}

app.use("/api", apiApp);

app.use(notFound);
app.use(errorHandler);

export default app;
