const express = require("express");
const path = require("path");
const cors = require("cors");
const compression = require("compression");
const dotenv = require("dotenv");
const { pool, ensureDatabase } = require("./db");
const playersRoutes = require("./routes/players");
const rankingsRoutes = require("./routes/rankings");
const { sendError } = require("./utils/http");
const { createApiRateLimiters } = require("./middleware/rate-limit");
const {
  createCorsMiddleware,
  securityHeaders,
  enforceHttps,
} = require("./middleware/security");

dotenv.config();

const app = express();
const PORT = Number(process.env.PORT || 3000);
const isDevelopment = process.env.NODE_ENV !== 'production';

const trustProxy = String(process.env.TRUST_PROXY || "false").toLowerCase() === "true";


app.set("trust proxy", trustProxy);
app.set("etag", "strong");

app.use(createCorsMiddleware());
app.use(securityHeaders);
app.use(enforceHttps);

app.use(
  compression({
    threshold: 1024,
    level: 6,
  })
);

app.use(
  express.json({
    limit: "32kb",
    strict: true,
    type: "application/json",
  })
);

const [ipRateLimit, userRateLimit] = createApiRateLimiters({
  ipMax: Number(process.env.RATE_LIMIT_IP_MAX || 60),
  userMax: Number(process.env.RATE_LIMIT_USER_MAX || 60),
  windowMs: Number(process.env.RATE_LIMIT_WINDOW_MS || 60 * 1000),
});

app.use("/api", ipRateLimit, userRateLimit);
app.use("/api", (_req, res, next) => {
  res.setHeader("Cache-Control", "no-store");
  next();
});

app.use(
  express.static(path.join(__dirname, "..", "public"), {
    etag: true,
    lastModified: true,
    maxAge: "1h",
    setHeaders(res, filePath) {
      const ext = path.extname(filePath).toLowerCase();

      if (ext === ".html") {
        res.setHeader("Cache-Control", "no-store");
        return;
      }

      if (filePath.includes(`${path.sep}assets${path.sep}`)) {
        res.setHeader("Cache-Control", "public, max-age=604800, immutable");
      } else {
        res.setHeader("Cache-Control", "public, max-age=3600");
      }
    },
  })
);

app.use("/api", playersRoutes);
app.use("/api", rankingsRoutes);

app.get("/api/health", async (_req, res) => {
  try {
    await pool.query("SELECT 1 AS ok");
    return res.json({ ok: true });
  } catch (_error) {
    return sendError(res, 500, "DB_UNAVAILABLE", "Database connection failed");
  }
});

app.use((err, _req, res, _next) => {
  if (err && /CORS origin blocked/i.test(String(err.message || ""))) {
    return sendError(res, 403, "CORS_BLOCKED", "Origin is not allowed.");
  }

  const isProd = String(process.env.NODE_ENV || "").toLowerCase() === "production";
  if (!isProd) {
    console.error("Unhandled error:", err);
  } else {
    console.error("Unhandled error:", err?.name || "UnknownError");
  }

  return sendError(res, 500, "INTERNAL_ERROR", "Internal server error");
});

async function startServer() {
  await ensureDatabase();

  app.listen(PORT, () => {
    console.log(`EaglerTiers API running on http://localhost:${PORT}`);
    console.log(`Environment: ${isDevelopment ? 'development' : 'production'}`);
  });
}

startServer().catch((error) => {
  console.error("Failed to start API:", error?.message || error);
  process.exit(1);
});
