const express = require("express");
const path = require("path");
const session = require("express-session");
const bcrypt = require("bcrypt");
const pool = require("./config/database");
require("dotenv").config();

const app = express();

const MySQLStore = require('express-mysql-session')(session);
const sessionStore = new MySQLStore({
    clearExpired: true,
    checkExpirationInterval: 900000,
    expiration: 86400000
}, pool);

const isLoggedIn = (req, res, next) => {
    if (req.session.user) {
        next();
    } else {
        res.redirect('/login');
    }
};

app.use(session({
    secret: process.env.SESSION_SECRET || "mysecret",
    resave: false,
    saveUninitialized: false,
    store: sessionStore,
    cookie: {
        maxAge: 24 * 60 * 60 * 1000,
        secure: false,
        httpOnly: true,
    },
}));

app.use(express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
    console.log("🔹 Session Data:", req.session);
    next();
});

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

const orderRoutes = require("./shop-routes/order");
const cartRoutes = require("./shop-routes/cart");
const indexRoutes = require("./shop-routes/index");

app.use((req, res, next) => {
    res.locals.session = req.session;
    next();
});

app.use("/", indexRoutes);
app.use("/cart", cartRoutes);
app.use("/order", orderRoutes);

app.get('/order/checkout', isLoggedIn, (req, res) => {
    res.render('checkout');
});

app.post("/cart/update", async (req, res) => {
    try {
        const { cartItemId, quantity } = req.body;

        if (quantity < 1) {
            return res.status(400).json({ message: "Quantity must be at least 1" });
        }

        // อัปเดตจำนวนสินค้าในฐานข้อมูล
        await pool.execute(
            "UPDATE cart SET quantity = ? WHERE id = ?",
            [quantity, cartItemId]
        );

        res.json({ success: true, message: "Cart updated" });
    } catch (error) {
        console.error("Update error:", error);
        res.status(500).json({ message: "Update failed" });
    }
});

app.get('/register', (req, res) => {
    res.render('register');
});

app.post("/register", async (req, res) => {
    try {
        const { email, password, name } = req.body;
        if (!email || !password || !name) {
            return res.status(400).json({ message: "All fields are required." });
        }
        
        const hashedPassword = await bcrypt.hash(password, 10);
        const [existingUser] = await pool.execute("SELECT * FROM users WHERE email = ?", [email]);
        
        if (existingUser.length > 0) {
            return res.status(400).json({ message: "Email is already registered." });
        }
        
        await pool.execute("INSERT INTO users (email, password, name) VALUES (?, ?, ?)", [email, hashedPassword, name]);
        res.status(201).json({ success: true, message: "Registration successful." });
    } catch (error) {
        res.status(500).json({ message: "Registration failed." });
    }
});

app.get('/login', (req, res) => {
    res.render('login');
});

app.post("/login", async (req, res) => {
    try {
        const { email, password } = req.body;
        if (!email || !password) {
            return res.status(400).json({ message: "All fields are required." });
        }
        
        const [users] = await pool.execute("SELECT * FROM users WHERE email = ?", [email]);
        if (users.length === 0) {
            return res.status(400).json({ message: "Invalid email or password." });
        }
        
        const user = users[0];
        const passwordMatch = await bcrypt.compare(password, user.password);
        if (!passwordMatch) {
            return res.status(400).json({ message: "Invalid email or password." });
        }

        req.session.user = { id: user.id, email: user.email };
        console.log("User logged in:", req.session);

        return res.redirect('/order/checkout');
    } catch (error) {
        res.status(500).json({ message: "Login failed." });
    }
});

// Logout Routes
app.get("/logout", (req, res) => {
    if (!req.session) {
        return res.redirect("/login");
    }
    req.session.destroy((err) => {
        if (err) {
            return res.status(500).json({ message: "Logout failed." });
        }
        res.clearCookie('connect.sid');
        console.log("User logged out.");
        res.redirect("/login");
    });
});

app.post("/logout", (req, res) => {
    if (!req.session) {
        return res.status(400).json({ message: "No active session." });
    }
    req.session.destroy(err => {
        if (err) {
            return res.status(500).json({ message: "Logout failed." });
        }
        res.clearCookie('connect.sid');
        console.log("User logged out (POST)");
        res.status(200).json({ message: "Logged out successfully" });
    });
});

app.get("/search", async (req, res) => {
    const searchQuery = req.query.query;
    try {
        const [results] = await pool.execute(
            "SELECT * FROM products WHERE name LIKE ? OR description LIKE ?",
            [`%${searchQuery}%`, `%${searchQuery}%`]
        );
        res.render("index", { products: results });
    } catch (err) {
        res.status(500).send("Error retrieving search results");
    }
});

app.use((err, req, res, next) => {
    res.status(500).json({ message: "Something went wrong." });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));