require("dotenv").config();
const express = require("express");
const mysql = require("mysql2");
const bodyParser = require("body-parser");
const bcrypt = require("bcryptjs");
const session = require("express-session");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const flash = require("connect-flash");

const app = express();
const port = 3000;

const db = mysql.createConnection({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
});

db.connect((err) => {
  if (err) throw err;
  console.log("Connected to MySQL Database");
});


app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));
app.set("view engine", "ejs");

app.use(session({ secret: "secret", resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());

app.use(flash());

// ตั้งค่า Passport สำหรับ Auth
passport.use(
  new LocalStrategy((username, password, done) => {
    db.query(
      "SELECT * FROM users WHERE username = ?",
      [username],
      async (err, results) => {
        if (err) return done(err);
        if (results.length === 0)
          return done(null, false, { message: "ไม่พบผู้ใช้" });

        const user = results[0];
        const match = await bcrypt.compare(password, user.password);
        if (!match) return done(null, false, { message: "รหัสผ่านไม่ถูกต้อง" });

        return done(null, user); // ตรวจสอบให้แน่ใจว่าได้ข้อมูลผู้ใช้ที่ถูกต้อง
      }
    );
  })
);


passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
  db.query("SELECT * FROM users WHERE id = ?", [id], (err, results) => {
    if (err) return done(err);
    done(null, results[0]); // ควรให้ข้อมูลผู้ใช้ถูกดึงมาอย่างถูกต้อง
  });
});


// Middleware เช็ค Login
const isAuthenticated = (req, res, next) => {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect("/login");
};


const isAdmin = (req, res, next) => {
  if (!req.isAuthenticated()) {
    return res.redirect("/login"); // ถ้าไม่ได้ login ให้ไปหน้า login
  }
  if (req.user.role !== "admin") {
    return res.status(403).send("Forbidden: คุณไม่มีสิทธิ์เข้าถึงหน้านี้");
  }
  next(); // ถ้าเป็น admin ให้ไปต่อ
};

passport.deserializeUser((id, done) => {
  db.query(
    "SELECT id, username, role FROM users WHERE id = ?",
    [id],
    (err, results) => {
      if (err) return done(err);
      done(null, results[0]); // ต้องแน่ใจว่า role ถูกส่งมาด้วย
    }
  );
});



// หน้า Login
app.get("/login", (req, res) => {
  res.render("login");
});

app.post(
  "/login",
  passport.authenticate("local", {
    successRedirect: "/",
    failureRedirect: "/login",
  })
);

// Logout
app.get("/logout", (req, res) => {
  req.logout(() => {
    res.redirect("/login");
  });
});

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

app.post("/register", async (req, res) => {
  const { username, password } = req.body;
  const hash = await bcrypt.hash(password, 10);

  // ทุกคนที่สมัครจากหน้าเว็บจะเป็น 'user' เท่านั้น
  const role = "user";

  db.query(
    "INSERT INTO users (username, password, role) VALUES (?, ?, ?)",
    [username, hash, role],
    (err) => {
      if (err) throw err;
      res.redirect("/login");
    }
  );
});



// ค้นหาอุปกรณ์
app.get("/", isAuthenticated, (req, res) => {
  const search = req.query.search || ""; // ตรวจสอบ search ให้แน่ใจว่ามีค่าเสมอ
  const searchQuery = `%${search}%`;

  db.query(
    "SELECT * FROM equipment WHERE name LIKE ?",
    [searchQuery],
    (err, equipment) => {
      if (err) throw err;
      res.render("index", { equipment, user: req.user, search }); // ส่งค่า search ไปยังหน้า EJS
    }
  );
});


// ยืมอุปกรณ์
// ยืมอุปกรณ์
app.post("/borrow", isAuthenticated, (req, res) => {
  const { equipment_id, quantity } = req.body;

  // ตรวจสอบจำนวนที่ต้องการยืม
  db.query(
    "SELECT quantity FROM equipment WHERE id = ?",
    [equipment_id],
    (err, results) => {
      if (err) throw err;

      const availableQuantity = results[0].quantity;
      if (availableQuantity >= quantity) {
        // ลดจำนวนอุปกรณ์ที่มีในระบบ
        db.query(
          "UPDATE equipment SET quantity = quantity - ? WHERE id = ?",
          [quantity, equipment_id],
          (err) => {
            if (err) throw err;

            // บันทึกข้อมูลการยืม (โดยใช้สถานะ 'pending' รอการยืนยัน)
            db.query(
              "INSERT INTO loans (equipment_id, user_id, quantity, status) VALUES (?, ?, ?, 'pending')",
              [equipment_id, req.user.id, quantity],
              (err) => {
                if (err) throw err;
                res.redirect("/loans");  // เปลี่ยนเส้นทางไปยังหน้า 'รวมการยืม'
              }
            );
          }
        );
      } else {
        res.send("จำนวนอุปกรณ์ไม่เพียงพอ");
      }
    }
  );
});



// คืนอุปกรณ์
app.post("/return", isAuthenticated, (req, res) => {
  const { equipment_id } = req.body;

  db.query(
    "UPDATE equipment SET quantity = quantity + 1, status = 'available' WHERE id = ?",
    [equipment_id],
    (err) => {
      if (err) throw err;

      db.query(
        "UPDATE loans SET returned_at = NOW() WHERE equipment_id = ? AND returned_at IS NULL",
        [equipment_id],
        (err) => {
          if (err) throw err;
          res.redirect("/");
        }
      );
    }
  );
});


app.get(
  "/manage",
  isAuthenticated,
  (req, res, next) => {
    console.log(req.user); // ตรวจสอบค่าที่ได้จาก session
    next();
  },
  isAdmin,
  (req, res) => {
    db.query("SELECT * FROM equipment", (err, equipment) => {
      if (err) throw err;
      res.render("manage", { equipment, user: req.user });
    });
  }
);



app.post("/add-equipment", isAuthenticated, (req, res) => {
  const { name, quantity } = req.body;
  db.query(
    "INSERT INTO equipment (name, quantity, status) VALUES (?, ?, 'available')",
    [name, quantity],
    (err) => {
      if (err) throw err;
      res.redirect("/manage");
    }
  );
});

// แสดงฟอร์มแก้ไขอุปกรณ์
app.get("/edit-equipment/:id", isAuthenticated, (req, res) => {
    const equipmentId = req.params.id;
    db.query("SELECT * FROM equipment WHERE id = ?", [equipmentId], (err, results) => {
        if (err) throw err;
        if (results.length === 0) {
            return res.status(404).send("ไม่พบอุปกรณ์ที่ต้องการแก้ไข");
        }
        const equipment = results[0];
        res.render("edit-equipment", { equipment });
    });
});

// ฟังก์ชันการแก้ไขอุปกรณ์
app.post("/edit-equipment", isAuthenticated, (req, res) => {
  const { id, name, quantity } = req.body;

  // ตรวจสอบว่าอุปกรณ์มีจำนวนเป็น 0 หรือไม่
  let status = quantity > 0 ? "available" : "unavailable";

  // อัปเดตชื่อและจำนวนอุปกรณ์
  db.query(
    "UPDATE equipment SET name = ?, quantity = ?, status = ? WHERE id = ?",
    [name, quantity, status, id],
    (err) => {
      if (err) throw err;
      res.redirect("/manage");
    }
  );
});

app.post("/delete-equipment", isAuthenticated, (req, res) => {
  const { id } = req.body;
  db.query("DELETE FROM equipment WHERE id = ?", [id], (err) => {
    if (err) throw err;
    res.redirect("/manage");
  });
});

// หน้าแสดงรายการการยืม
app.get("/loans", (req, res) => {
  if (req.user && req.user.role === "user") {
    db.query(
      `SELECT loans.id, loans.quantity, loans.status, equipment.name AS equipment_name 
       FROM loans 
       JOIN equipment ON loans.equipment_id = equipment.id 
       WHERE loans.user_id = ?`,
      [req.user.id],
      (err, loans) => {
        if (err) {
          return res.status(500).send("Error retrieving loans");
        }
        // ส่งข้อมูลทั้ง loans และ equipment ไปยัง EJS
        res.render("loans", { loans: loans, user: req.user });
      }
    );
  } else {
    res.redirect("/"); // ถ้าไม่ได้ล็อกอินหรือไม่ใช่ผู้ใช้ ให้กลับไปหน้าแรก
  }
});



// หน้าแสดงรายการการยืมสำหรับ Admin
app.get("/admin-loans", (req, res) => {
  if (req.isAuthenticated() && req.user.role === "admin") {
    // Query ดึงข้อมูลการยืม
    db.query(
      'SELECT loans.id, users.username, equipment.name AS equipment_name, loans.quantity, loans.status FROM loans JOIN users ON loans.user_id = users.id JOIN equipment ON loans.equipment_id = equipment.id WHERE loans.status = "pending"',
      (err, loans) => {
        if (err) throw err;
        res.render("admin-loans", { user: req.user, loans: loans }); // ส่งข้อมูล user และ loans
      }
    );
  } else {
    res.redirect("/login"); // ถ้าไม่ใช่ผู้ดูแลระบบ ให้ไปที่หน้า login
  }
});




// ยืนยันการยืม (สำหรับ Admin)
// อนุมัติหรือปฏิเสธคำขอยืม (สำหรับ Admin)
app.post("/approve-loan", isAuthenticated, isAdmin, (req, res) => {
  const { loan_id, action } = req.body;

  // กำหนดสถานะใหม่
  let newStatus = action === 'approve' ? 'approved' : 'rejected';

  // อัปเดตสถานะในฐานข้อมูล
  db.query(
    "UPDATE loans SET status = ? WHERE id = ?",
    [newStatus, loan_id],
    (err) => {
      if (err) throw err;
      res.redirect("/admin-loans");  // หลังจากอนุมัติหรือปฏิเสธเสร็จ, กลับไปที่หน้าการจัดการการยืม
    }
  );
});

// Route แสดงหน้าการยืนยันการยืม
app.post("/confirm-loan", (req, res) => {
  if (!req.user) {
    return res.redirect("/login"); // หากไม่ได้ล็อกอิน ให้กลับไปที่หน้า login
  }

  const equipment_id = req.body.equipment_id;
  const quantity = req.body.quantity;

  // ดึงข้อมูลอุปกรณ์จากฐานข้อมูล
  db.query(
    "SELECT * FROM equipment WHERE id = ?",
    [equipment_id],
    (err, result) => {
      if (err) throw err;
      const equipment = result[0];

      // ส่งข้อมูล user ไปยัง confirm-loan.ejs
      res.render("confirm-loan", { equipment, quantity, user: req.user });
    }
  );
});


// Route สำหรับยืนยันการยืม
app.post('/submit-loan', (req, res) => {
    const user_id = req.user.id; // สมมติว่าผู้ใช้ล็อกอินแล้ว
    const equipment_id = req.body.equipment_id;
    const quantity = req.body.quantity;

    // ตรวจสอบว่าอุปกรณ์มีจำนวนเพียงพอหรือไม่
    db.query('SELECT * FROM equipment WHERE id = ?', [equipment_id], (err, result) => {
        if (err) throw err;
        const equipment = result[0];

        if (equipment.quantity >= quantity) {
            // บันทึกข้อมูลการยืมลงในตาราง loans
            db.query('INSERT INTO loans (user_id, equipment_id, quantity, status) VALUES (?, ?, ?, "pending")', [user_id, equipment_id, quantity], (err) => {
                if (err) throw err;
                // ปรับจำนวนอุปกรณ์ในตาราง equipment
                db.query('UPDATE equipment SET quantity = quantity - ? WHERE id = ?', [quantity, equipment_id], (err) => {
                    if (err) throw err;
                    res.redirect('/loans'); // เปลี่ยนเส้นทางไปยังหน้า "รวมการยืมอุปกรณ์"
                });
            });
        } else {
            res.send('จำนวนอุปกรณ์ไม่เพียงพอ');
        }
    });
});

// การยกเลิกการยืม (Backend)
app.post("/cancel-loan", (req, res) => {
  const loanId = req.body.loan_id;
  const userId = req.user.id;

  const query = "DELETE FROM loans WHERE id = ? AND user_id = ?";
  db.query(query, [loanId, userId], (err, result) => {
    if (err) {
      console.error(err);
      return res.redirect("/loans");
    }

    // ใช้ flash message หลังจากการลบสำเร็จ
    req.flash("success", "การยืมอุปกรณ์ถูกยกเลิกแล้ว");
    res.redirect("/loans");
  });
});


app.get("/return-equipment", (req, res) => {
  // ดึงข้อมูลจากฐานข้อมูล
  db.query(
    "SELECT * FROM loans WHERE user_id = ?",
    [req.session.user_id],
    (err, results) => {
      if (err) {
        console.error(err);
        return res.status(500).send("Database query error");
      }
      console.log(results); // ตรวจสอบว่า loans ถูกดึงมาจริงๆ
      res.render("return-equipment", {
        loans: results,
        user: req.session.user,
      });
    }
  );
});

app.post("/return-equipment", (req, res) => {
  const loanId = req.body.loan_id;
  const userId = req.user.id; // Assume user is logged in and user.id is available

  // ตรวจสอบว่าผู้ใช้คือผู้ที่ยืมอุปกรณ์จริงหรือไม่
  db.query(
    "SELECT * FROM loans WHERE id = ? AND user_id = ?",
    [loanId, userId],
    (err, results) => {
      if (err) {
        return res.status(500).send("เกิดข้อผิดพลาดในการเข้าถึงฐานข้อมูล");
      }

      if (results.length === 0) {
        return res.status(404).send("ไม่พบการยืมอุปกรณ์นี้");
      }

      const loan = results[0];
      if (loan.status === "returned") {
        return res.status(400).send("อุปกรณ์นี้ได้ถูกคืนแล้ว");
      }

      // อัพเดตสถานะการคืนอุปกรณ์
      db.query(
        'UPDATE loans SET status = "returned" WHERE id = ?',
        [loanId],
        (err, result) => {
          if (err) {
            return res.status(500).send("เกิดข้อผิดพลาดในการคืนอุปกรณ์");
          }
          res.redirect("/return-equipment"); // กลับไปที่หน้า "คืนอุปกรณ์"
        }
      );
    }
  );
});

function confirmReturn(button) {
  const loanId = button.getAttribute("data-loan-id");
  console.log("Loan ID:", loanId); // ตรวจสอบค่า loanId
  const confirmation = confirm("คุณแน่ใจหรือไม่ว่าต้องการคืนอุปกรณ์นี้?");
  if (confirmation) {
    document.getElementById("loan_id").value = loanId;
    document.getElementById("returnForm").submit();
  }
}








app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});