import express from "express";
import helmet from "helmet";
import morgan from "morgan";
import path from "path";
import { fileURLToPath } from "url";
import { loadSwiEnv } from "./config/loadEnv.js";
import apiRouter from "./routes/index.js";
import { notFound, errorHandler } from "./middlewares/errorHandler.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
export const API_PREFIX = "/api/swi";

loadSwiEnv();

export function createSwiApp() {
  const app = express();

  app.use(
    helmet({
      crossOriginResourcePolicy: { policy: "cross-origin" },
    })
  );
  app.use(express.json({ limit: "50mb" }));
  app.use(express.urlencoded({ extended: true, limit: "50mb" }));

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

  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(
    "/uploads",
    express.static(path.join(__dirname, "..", "uploads"))
  );

  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(API_PREFIX, apiApp);

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

  return app;
}

export default createSwiApp();
