require("dotenv").config();

const express = require("express");
const cors = require("cors");
const helmet = require("helmet");
const morgan = require("morgan");
const rateLimit = require("express-rate-limit");
const { query } = require("./db");
const {
  cacheMiddleware,
  invalidationMiddleware,
  getCacheStats,
  startCacheCleanup,
} = require("./middleware/cache");

// Import routes
const authRoutes = require("./routes/auth");
const songsRoutes = require("./routes/songs");
const listsRoutes = require("./routes/lists");
const profilesRoutes = require("./routes/profiles");
const adminRoutes = require("./routes/admin");

const app = express();
const PORT = process.env.PORT || 8080;

// Start cache cleanup (every 60 seconds)
startCacheCleanup(60000);

// Security middleware
app.use(
  helmet({
    contentSecurityPolicy: false, // Disable for development
  }),
);

// CORS configuration
const allowedOrigins = [
  "http://localhost:5100",
  "http://localhost:3000",
  "https://houseofprayer.ddns.net",
  "http://houseofprayer.ddns.net",
];

app.use(
  cors({
    origin: (origin, callback) => {
      // Allow requests with no origin (like mobile apps or curl requests)
      if (!origin) return callback(null, true);

      if (allowedOrigins.includes(origin)) {
        callback(null, true);
      } else {
        // For development, allow all origins
        callback(null, true);
      }
    },
    credentials: true,
    methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
    allowedHeaders: ["Content-Type", "Authorization", "If-None-Match"],
    exposedHeaders: ["ETag", "X-Cache", "Cache-Control"],
  }),
);

// Explicit OPTIONS handler for preflight requests
app.options("*", cors());

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 1000, // Generous limit for development
  message: { error: "Too many requests, please try again later." },
});
app.use("/api/", limiter);

// Body parsing
app.use(express.json({ limit: "10mb" }));
app.use(express.urlencoded({ extended: true, limit: "10mb" }));

// Response caching middleware (applies to GET requests)
app.use("/api/", cacheMiddleware());

// Cache invalidation middleware (handles POST, PUT, DELETE)
app.use("/api/", invalidationMiddleware);

// Logging (compact format for production-like environment)
app.use(morgan("dev"));

// Health check
app.get("/health", (req, res) => {
  res.json({ status: "ok", timestamp: new Date().toISOString() });
});

// Cache stats endpoint for monitoring
app.get("/api/cache-stats", (req, res) => {
  res.json({
    success: true,
    cache: getCacheStats(),
    timestamp: new Date().toISOString(),
  });
});

// Stats endpoint for dashboard
app.get("/api/stats", async (req, res) => {
  try {
    const [songsResult, profilesResult, listsResult] = await Promise.all([
      query("SELECT COUNT(*) as count FROM songs"),
      query("SELECT COUNT(*) as count FROM profiles"),
      query("SELECT COUNT(*) as count FROM plans"),
    ]);

    res.json({
      success: true,
      stats: {
        songs: parseInt(songsResult.rows[0].count),
        profiles: parseInt(profilesResult.rows[0].count),
        lists: parseInt(listsResult.rows[0].count),
      },
    });
  } catch (err) {
    console.error("Stats error:", err);
    res.status(500).json({ success: false, message: "Failed to fetch stats" });
  }
});

// API Routes
app.use("/api/auth", authRoutes);
app.use("/api/songs", songsRoutes);
app.use("/api/lists", listsRoutes);
app.use("/api/profiles", profilesRoutes);
app.use("/api/admin", adminRoutes);

// 404 handler for API routes
app.use((req, res) => {
  res.status(404).json({ error: "Not found" });
});

// Error handler
app.use((err, req, res, next) => {
  console.error("Server error:", err);
  res.status(500).json({ error: "Internal server error" });
});

// Start server
app.listen(PORT, () => {
  console.log("🚀 Server running on http://localhost:" + PORT);
  console.log("📊 Health check: http://localhost:" + PORT + "/health");
});

module.exports = app;
