const express = require("express");
const dotenv = require("dotenv");
const path = require("path");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const flash = require("connect-flash");
const expressLayouts = require("express-ejs-layouts");
const fs = require("fs");

// Load environment variables
dotenv.config();

const connectDB = require("./config/database");

// Connect to MongoDB
connectDB();

// Initialize express app
const app = express();

// Set view engine
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));

// Set up express-ejs-layouts
app.use(expressLayouts);
app.set("layout", "layouts/main");
app.set("layout extractScripts", true);
app.set("layout extractStyles", true);

// Middlewares
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(
    "/assets",
    (req, res, next) => {
        // Cho phép mọi domain truy cập tài nguyên tĩnh
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Methods", "GET");
        next();
    },
    express.static(path.join(__dirname, "assets")),
);

// Serve public folder at root (for /js, /img, etc.)
app.use(express.static(path.join(__dirname, "public")));

// Serve uploads folder
app.use(
    "/uploads",
    (req, res, next) => {
        // Cho phép mọi domain truy cập tài nguyên tĩnh
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Methods", "GET");
        next();
    },
    express.static(path.join(__dirname, "public", "uploads")),
);

// Serve other public files
app.use(express.static(path.join(__dirname, "public")));

// Session configuration (using MongoDB store to avoid logout khi server restart)
app.use(
    session({
        secret: process.env.SESSION_SECRET || "secret",
        resave: false,
        saveUninitialized: false,
        store: MongoStore.create({
            mongoUrl: process.env.MONGODB_URI,
            collectionName: "sessions",
            ttl: 60 * 60 * 24, // 24 hours (in seconds)
        }),
        cookie: {
            maxAge: 1000 * 60 * 60 * 24, // 24 hours
            httpOnly: true,
            sameSite: "lax",
        },
    }),
);

// Flash messages
app.use(flash());

// Global variables
app.use((req, res, next) => {
    // Lấy flash messages
    const success_msg = req.flash("success_msg");
    const error_msg = req.flash("error_msg");
    const error = req.flash("error");

    // Lưu vào res.locals để sử dụng trong views
    res.locals.success_msg = success_msg.length > 0 ? success_msg[0] : null;
    res.locals.error_msg = error_msg.length > 0 ? error_msg[0] : null;
    res.locals.error = error.length > 0 ? error[0] : null;

    // Tạo object flashMessages để sử dụng trong client-side JavaScript
    res.locals.flashMessagesJSON = JSON.stringify({
        success_msg: res.locals.success_msg,
        error_msg: res.locals.error_msg,
        error: res.locals.error,
    });

    res.locals.user = req.session.user || null;
    res.locals.currentPath = req.path;
    next();
});

// Kiểm tra và tạo thư mục data nếu chưa tồn tại
const dataDir = path.join(__dirname, "data");
if (!fs.existsSync(dataDir)) {
    fs.mkdirSync(dataDir);
}

// Frontend URL configuration
const FRONTEND_URL = process.env.FRONTEND_URL;

// Add frontend URL to res.locals for all requests
app.use((req, res, next) => {
    res.locals.frontendUrl = FRONTEND_URL;
    res.locals.currentPath = req.path;
    next();
});

// Simple CORS middleware for API endpoints
app.use((req, res, next) => {
    // Allow requests from configured FRONTEND_URL or allow all if not set
    const origin = req.headers.origin;
    const allowedOrigin = FRONTEND_URL || "*";

    if (allowedOrigin === "*" || origin === allowedOrigin) {
        res.setHeader("Access-Control-Allow-Origin", allowedOrigin === "*" ? "*" : origin);
        res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
        res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        res.setHeader("Access-Control-Allow-Credentials", "true");
    }

    // Handle preflight
    if (req.method === "OPTIONS") {
        return res.sendStatus(204);
    }

    next();
});

// Routes
const authRoutes = require("./routes/auth");
const adminRoutes = require("./routes/admin");
const indexRoutes = require("./routes/index");

app.use("/auth", authRoutes);
app.use("/admin", adminRoutes);
app.use("/", indexRoutes);

// 404 handler
app.use((req, res) => {
    res.status(404);
    if (req.accepts("html"))
        return res.render("page/404", {
            title: "404 - Page Not Found",
            layout: "layouts/main",
        });
    if (req.accepts("json")) return res.json({ error: "Not found" });
    res.type("txt").send("Not found");
});

// Start server
const PORT = process.env.PORT || 3001;
const HOST = process.env.HOST || "localhost";
app.listen(PORT, HOST, () => {
    console.log(`🚀 SERVER:[ http://${HOST}:${PORT} ]`);
});
