import express from "express";
import cors from "cors";
import helmet from "helmet";
import compression from "compression";
import morgan from "morgan";
import swaggerUi from "swagger-ui-express";
import swaggerSpec from "./config/swagger.js";
import { globalLimiter } from "./middlewares/rateLimiter.js";
import apiRoutes from "./routes/api.js";
import db from "./models/index.js";
import path from "path";
import { fileURLToPath } from "url";

import { docsAuth } from "./middlewares/docsAuthMiddleware.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();

app.set('trust proxy', 1);

app.use(helmet({
  contentSecurityPolicy: false, 
  crossOriginResourcePolicy: { policy: "cross-origin" },
  crossOriginOpenerPolicy: { policy: "unsafe-none" }
}));
app.use(compression());

// Explicit CORS configuration to allow custom headers used by the SaaS
const allowedOrigins = process.env.ALLOWED_ORIGINS 
  ? process.env.ALLOWED_ORIGINS.split(",") 
  : [process.env.FRONTEND_URL || "http://localhost:3000"];

app.use(cors({
  origin: function (origin, callback) {
    // allow requests with no origin (like mobile apps or curl requests)
    if (!origin) return callback(null, true);
    
    if (allowedOrigins.indexOf(origin) === -1 && !allowedOrigins.includes("*")) {
      var msg = 'The CORS policy for this site does not allow access from the specified Origin.';
      return callback(new Error(msg), false);
    }
    return callback(null, true);
  },
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization", "x-public-key", "x-private-key", "X-Airpero-Event", "x-signature-v2"],
  credentials: true
}));
app.use(express.json());
app.use(morgan("dev"));

// Global Rate Limiting
app.use("/api", globalLimiter);

// Static Files (for documentation portal)
app.use("/docs", express.static(path.join(__dirname, "../public/docs")));

// Swagger API Documentation (Protected)
app.use("/api-docs", docsAuth, swaggerUi.serve, swaggerUi.setup(swaggerSpec));

app.use("/api/v1", apiRoutes);

app.get("/", (req, res) => {
  res.status(200).json({ status: "Airpero SaaS Operational" });
});

// Database sync (skip auto-connect in test environment)
if (process.env.NODE_ENV !== "test") {
  db.sequelize.authenticate()
    .then(() => {
      console.log("✅ SaaS Database connected");
      // db.sequelize.sync({ alter: true }); // Sync in Dev, use migrations in Prod
    })
    .catch((err) => {
      const isRefused = err.original?.code === "ECONNREFUSED" || err.name === "SequelizeConnectionRefusedError";
      if (isRefused) {
        console.error(`❌ Database Connection Error: Cannot connect to MySQL (${err.message})`);
        console.error(`👉 ACTION REQUIRED: Ensure your local MySQL service is running. If MySQL is running on default port 3306, set DB_PORT=3306 in your .env file.`);
      } else {
        console.error("❌ Database Connection Error:", err.message);
      }
    });
}

// Global Error Handler
app.use((err, req, res, next) => {
    console.error("💥 Unhandled Error:", err.stack);
    res.status(err.status || 500).json({
        success: false,
        message: err.message || "Internal Server Error",
        error: process.env.NODE_ENV === "development" ? err.stack : undefined
    });
});

export default app;
