const express = require("express");
const router = express.Router();
const bcrypt = require('bcryptjs');
const multer = require('multer');
const fs = require('fs');
const passport = require('passport');
const session = require('express-session');
const bodyparser = require('body-parser');
const cookieParser = require('cookie-parser');
const User = require('../models/User');
const Order = require("../models/Order");
const ExcelJS = require('exceljs');
const LicenseInfo = require('../models/LicenseInfo');
const QRCode = require('qrcode');
const QRitem = require('../models/Qritem');
// Library for detecting timzones
const { DateTime } = require('luxon');

const crypto = require("crypto");
const { sendEmail } = require("../config/mail");

const Item = require('../models/Item');
const Review = require('../models/Review');
const Reservation = require('../models/Reservation');


const MAX_GUESTS_PER_SLOT = parseInt(process.env.MAX_GUESTS_PER_SLOT) || 50; 
// 50 is default agar env variable set nahi hai to



const guest = require('../middleware/guest');

const { forwardAuthenticated, ensureAuthenticated } = require('../config/auth');

router.use(bodyparser.urlencoded({ extended: true }));

router.use(cookieParser('secret'));
router.use(session({
  secret: 'secret',
  maxAge: 3600000,
  resave: true,
  saveUninitialized: true,
}));

// Image Upload
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './public/uploads');
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
  },
});

var upload = multer({
  storage: storage,
}).single("image");


// My Code starts here

router.get('/admin-dashboard', ensureAuthenticated, async (req, res) => {
  res.render('admin-dashboard');
});

router.get('/user-profile', ensureAuthenticated, async (req, res) => {
  res.render('user-profile');
});


// First-time setup route
router.get('/demo-setup', async (req, res) => {
  const license = await LicenseInfo.findOne();
  if (license) return res.redirect('/dashboard');

  res.render('demo-setup'); // Render form for demo setup
});

router.post('/demo-setup', async (req, res) => {
  const { customerName, phone, demoLicenseKey } = req.body;

  const demoStartDate = new Date();
  const demoEndDate = new Date(demoStartDate.getTime() + 5 * 24 * 60 * 60 * 1000);

  await LicenseInfo.create({
    customerName,
    phone,
    demoLicenseKey,
    demoStartDate,
    demoEndDate
  });

  res.redirect('/dashboard');
});

// One code for both item and review on index page
router.get("/", async (req, res) => {
  try {
    const items = await Item.find();     // Fetch all items
    const reviews = await Review.find(); // Fetch all reviews

    res.render("index", { items, reviews });
  } catch (err) {
    console.error(err);
    res.status(500).render("error", { message: "Something went wrong!" });
  }
});

router.get('/dashboard', ensureAuthenticated, async (req, res) => {
  try {
    const userTz = req.cookies.timezone || 'UTC';
    const currentHour = DateTime.now().setZone(userTz).hour;

    let greeting = '';
    if (currentHour >= 5 && currentHour < 12) {
      greeting = 'Good morning';
    } else if (currentHour >= 12 && currentHour < 17) {
      greeting = 'Good afternoon';
    } else if (currentHour >= 17 && currentHour < 22) {
      greeting = 'Good evening';
    } else {
      greeting = 'Hello';
    }

    const customerName = req.user?.name || req.user?.fullName || req.user?.username || 'Customer';

    const startOfDay = DateTime.now().setZone(userTz).startOf('day').toUTC();
    const endOfDay = DateTime.now().setZone(userTz).endOf('day').toUTC();

    const todayEarningsResult = await Order.aggregate([
      {
        $match: {
          created_at: { $gte: startOfDay.toJSDate(), $lte: endOfDay.toJSDate() }
        }
      },
      {
        $group: {
          _id: null,
          earnings: { $sum: "$total" }
        }
      }
    ]);
    const todayEarnings = todayEarningsResult[0]?.earnings || 0;

    const totalOrdersToday = await Order.countDocuments({
      created_at: { $gte: startOfDay.toJSDate(), $lte: endOfDay.toJSDate() }
    });

    const totalReservationsToday = await Reservation.countDocuments({
      created_at: { $gte: startOfDay.toJSDate(), $lte: endOfDay.toJSDate() }
    });

    const totalReviewsToday = await Review.countDocuments({
      created_at: { $gte: startOfDay.toJSDate(), $lte: endOfDay.toJSDate() }
    });

    const lastMonthStart = DateTime.now().setZone(userTz).minus({ months: 1 }).startOf('month').toUTC();
    const lastMonthEnd = DateTime.now().setZone(userTz).minus({ months: 1 }).endOf('month').toUTC();

    const lastMonthStats = await Order.aggregate([
      {
        $match: {
          created_at: {
            $gte: lastMonthStart.toJSDate(),
            $lte: lastMonthEnd.toJSDate()
          }
        }
      },
      {
        $group: {
          _id: null,
          totalEarnings: { $sum: "$total" },
          totalOrders: { $sum: 1 }
        }
      }
    ]);

    const lastMonthEarnings = lastMonthStats[0]?.totalEarnings || 0;
    const lastMonthOrders = lastMonthStats[0]?.totalOrders || 0;
    const lastMonthDays = lastMonthEnd.diff(lastMonthStart, 'days').days;

    const avgDailyEarnings = lastMonthDays > 0 ? lastMonthEarnings / lastMonthDays : 0;
    const avgDailyOrders = lastMonthDays > 0 ? lastMonthOrders / lastMonthDays : 0;

    const earningsChangePercent = avgDailyEarnings > 0
      ? ((todayEarnings - avgDailyEarnings) / avgDailyEarnings) * 100
      : 0;

    const ordersChangePercent = avgDailyOrders > 0
      ? ((totalOrdersToday - avgDailyOrders) / avgDailyOrders) * 100
      : 0;

    // 🔍 Search logic
    const osearch = req.query.search || "";
    let searchFilter = {};

    if (osearch) {
      const numericSearch = !isNaN(osearch);

      searchFilter = {
        $or: [
          { tableNumber: { $regex: osearch, $options: "i" } },

          ...(numericSearch ? [
            { total: parseFloat(osearch) }
          ] : []),

          { "items.name": { $regex: osearch, $options: "i" } }
        ]
      };
    }

    const orders = await Order.find(searchFilter).sort({ created_at: -1 });

    res.render('dashboard', {
      greeting,
      customerName,
      orders,
      search: osearch, // <-- ✅ This is what fixes the EJS error
      todayEarnings,
      totalOrdersToday,
      totalReservationsToday,
      totalReviewsToday,
      earningsChangePercent: Math.round(earningsChangePercent),
      ordersChangePercent: Math.round(ordersChangePercent)
    });

  } catch (error) {
    console.error('Dashboard fetch error:', error);
    res.render('dashboard', {
      greeting: 'Hello',
      customerName: 'Customer',
      todayEarnings: 0,
      totalOrdersToday: 0,
      totalReservationsToday: 0,
      totalReviewsToday: 0,
      earningsChangePercent: 0,
      ordersChangePercent: 0,
      orders: [],
      search: '' // ✅ Prevents "search is not defined"
    });
  }
});







// Login Page
router.get('/signin', guest, forwardAuthenticated, (req, res) => res.render('signin'));

// OTP Login Page
router.get('/otp-login', guest, forwardAuthenticated, (req, res) => res.render('otp-login'));

// Register Page
router.get('/signup', guest, forwardAuthenticated, (req, res) => res.render('signup'));

// Register
router.post('/signup', async (req, res) => {
  const { name, email, password, password2 } = req.body;

  // Name validation (First Last or First Middle Last, capitalized)
  const nameRegex = /^([A-Z][a-z]+)(\s[A-Z][a-z]+){1,2}$/;
  if (!nameRegex.test(name)) {
    req.flash("error_msg", "Please enter a valid name (First Last or First Middle Last)");
    return res.redirect("/signup");
  }

  if (!name || !email || !password || !password2) {
    req.flash('error_msg', 'Please enter all fields.');
    return res.redirect('/signup');
  }

  if (password !== password2) {
    req.flash('error_msg', 'Passwords do not match.');
    return res.redirect('/signup');
  }

  if (password.length < 6) {
    req.flash('error_msg', 'Password must be at least 6 characters long.');
    return res.redirect('/signup');
  }

  // Check if user already exists
  const user = await User.findOne({ email });
  if (user) {
    req.flash('error_msg', 'Email already exists.');
    return res.redirect('/signup');
  }
  // Create new user
  const newUser = new User({ name, email, password });

  bcrypt.genSalt(10, (err, salt) => {
    if (err) throw err;
    bcrypt.hash(newUser.password, salt, async (err, hash) => {
      if (err) throw err;
      newUser.password = hash;
      try {
        await newUser.save();
        req.flash('success_msg', 'You are now registered and can log in.');
        res.redirect('/signin');
      } catch (err) {
        console.log(err);
        req.flash('error_msg', 'Something went wrong. Please try again.');
        res.redirect('/signup');
      }
    });
  });
});



// Login with role
const _getRedirectUrl = (req) => {
  if (req.user.role === 'owner') {
    return '/admin-dashboard';
  } else if (req.user.role === 'admin') {
    return '/dashboard';
  } else {
    return '/';
  }
}
router.post('/signin', (req, res, next) => {
  passport.authenticate('local', (err, user, info) => {
    if (err) {
      req.flash('error', info.message)
      return next(err)
    }
    if (!user) {
      req.flash('error', info.message)
      return res.redirect('/signin')
    }
    req.logIn(user, (err) => {
      if (err) {
        req.flash('error', info.message)
        return next(err)
      }
      return res.redirect(_getRedirectUrl(req))
    })
  })(req, res, next);
});


// Logout
router.get('/logout', function (req, res, next) {
  req.logout(function (err) {
    if (err) { return next(err); }
    req.flash('success_msg', 'You have logged out.');
    res.redirect('/');
  });
});


// ===== FORGET PASSWORD PAGE =====
router.get("/forgot-password", (req, res) => {
  res.render("forgot-password", { message: "" });
});

// ===== SEND OTP =====
router.post("/forgot-password", async (req, res) => {
  const { email } = req.body;
  const user = await User.findOne({ email });
  if (!user) {
    req.flash('error_msg', 'Email not found!');
    return res.redirect("/forgot-password");
  }

  // Generate 6-digit OTP
  const otp = Math.floor(100000 + Math.random() * 900000).toString();

  // Set OTP expiry 15 min
  user.resetOTP = otp;
  user.resetOTPExpiry = Date.now() + 15 * 60 * 1000;
  await user.save();

  // Send OTP Email
  const html = `<p>Your OTP for password reset is: <b>${otp}</b></p>`;
  await sendEmail({
    email: user.email,
    subject: "Password Reset OTP",
    html: html
  });

  req.flash('success_msg', 'OTP sent to your email.');
  res.render("verify-otp", { email });
});


// ===== VERIFY OTP =====
router.post("/verify-otp", async (req, res) => {
  const { email, otp } = req.body;

  const user = await User.findOne({ email });
  if (!user) {
    req.flash('error_msg', 'User not found.');
    return res.redirect("/forgot-password");
  }

  if (user.resetOTP !== otp || Date.now() > user.resetOTPExpiry) {
    req.flash('error_msg', 'Invalid or expired OTP.');
    return res.redirect("/forgot-password");
  }

  // OTP is valid → redirect to reset password page
  req.flash('success_msg', 'OTP verified. You can reset your password now.');
  res.render("reset-password", { email });
});


router.post("/reset-password", async (req, res) => {
  const { email, password, password2 } = req.body;

  if (!password || !password2) {
    req.flash('error_msg', 'Please fill all fields.');
    return res.redirect('back');
  }

  if (password !== password2) {
    req.flash('error_msg', 'Passwords do not match.');
    return res.redirect('back');
  }

  const user = await User.findOne({ email });
  if (!user) {
    req.flash('error_msg', 'User not found.');
    return res.redirect("/forgot-password");
  }

  const salt = await bcrypt.genSalt(10);
  user.password = await bcrypt.hash(password, salt);

  // Clear OTP
  user.resetOTP = null;
  user.resetOTPExpiry = null;

  await user.save();
  req.flash('success_msg', 'Password updated. You can now login.');
  res.redirect('/signin');
});



router.get("/add-items", ensureAuthenticated, async (req, res) => {
  try {
    // Get user timezone from cookies or fallback to UTC
    const userTz = req.cookies.timezone || "UTC";

    // Determine greeting based on user time
    const currentHour = DateTime.now().setZone(userTz).hour;
    let greeting = "";
    if (currentHour >= 5 && currentHour < 12) {
      greeting = "Good morning";
    } else if (currentHour >= 12 && currentHour < 17) {
      greeting = "Good afternoon";
    } else if (currentHour >= 17 && currentHour < 22) {
      greeting = "Good evening";
    } else {
      greeting = "Hello";
    }

    const customerName = req.user?.name || req.user?.fullName || req.user?.username || 'Customer';


    // Search query parameter
    const search = req.query.search || "";

    // Build search filter if search exists
    let query = {};
    if (search) {
      query = {
        $or: [
          { itemName: { $regex: search, $options: "i" } },
          { category: { $regex: search, $options: "i" } },
          { subCategory: { $regex: search, $options: "i" } },
          { description: { $regex: search, $options: "i" } },
        ],
      };
    }

    // Find items with filter or all
    const items = await Item.find(query).sort({ created_at: -1 });

    // Render with greeting and items
    res.render("add-items", {
      items,
      search,
      greeting,
      customerName,
    });
  } catch (err) {
    console.error(err);
    req.flash("error_msg", "Error fetching items");
    res.redirect("/dashboard");
  }
});



router.post("/add-items", upload, async (req, res) => {
  try {
    // Check if file was uploaded
    if (!req.file) {
      req.flash('error_msg', 'Image upload failed.');
      return res.redirect('/add_listing');
    }

    const newItem = new Item({
      itemName: req.body.itemName,
      price: req.body.price,
      category: req.body.category,
      subCategory: req.body.subCategory,
      description: req.body.description,
      image: req.file.filename,
      customerId: req.user._id,  // ✅ This connects item to logged-in customer
    });

    await newItem.save();
    req.flash('success_msg', 'Item Added Successfully.');
    res.redirect('/add-items');

  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Unable to add item. Please try again.');
    res.redirect('/add-items');
  }
});

// This will be used when the form in modal is submitted
router.post("/update/:id", upload, async (req, res) => {
  let id = req.params.id;
  let new_image = "";

  if (req.file) {
    new_image = req.file.filename;
    try {
      fs.unlinkSync('./public/uploads/' + req.body.old_image);
    } catch (err) {
      console.log(err);
    }
  } else {
    new_image = req.body.old_image;
  }

  const update = {
    itemName: req.body.itemName,
    price: req.body.price,
    category: req.body.category,
    subCategory: req.body.subCategory,
    description: req.body.description,
    image: new_image,
  };

  try {
    await Item.findByIdAndUpdate(id, update, { new: true });
    req.flash('success_msg', 'Item Updated Successfully..');
    res.redirect('/add-items'); // This will reload your page with updated data
  } catch (err) {
    req.flash('error_msg', 'Unable to update Item..');
    res.redirect('/add-items');
  }
});

router.get('/delete/:id', async (req, res) => {
  try {
    const item = await Item.findById(req.params.id);
    if (!item) {
      req.flash('error_msg', 'Item not found');
      return res.redirect('/add-items');
    }

    // Delete image file from disk (optional)
    if (item.image) {
      const imagePath = './public/uploads/' + item.image;
      if (fs.existsSync(imagePath)) {
        fs.unlinkSync(imagePath);
      }
    }

    await Item.findByIdAndDelete(req.params.id);
    req.flash('success_msg', 'Item deleted successfully');
    res.redirect('/add-items');
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error deleting item');
    res.redirect('/add-items');
  }
});

// Reviews On frontend
router.get("/reviews", (req, res) => {
  res.render("reviews");
});
// Post Reviews On frontend
router.post("/add_reviews", upload, async (req, res) => {
  try {
    // Check if file was uploaded
    if (!req.file) {
      req.flash('error_msg', 'Image upload failed.');
      return res.redirect('/reviews');
    }

    const newReview = new Review({
      cname: req.body.name,
      review: req.body.review,
      image: req.file.filename,
      customerId: req.user._id,  // ✅ This connects item to logged-in customer
    });

    await newReview.save();
    req.flash('success_msg', 'Review Added Successfully.');
    res.redirect('/reviews');

  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Unable to add review. Please try again.');
    res.redirect('/reviews');
  }
});

// Get reviews on dashboard for editing


// ==== Reviews List + Search ====
router.get("/edit-reviews", ensureAuthenticated, async (req, res) => {
  try {

        // Get user timezone from cookies or fallback to UTC
    const userTz = req.cookies.timezone || "UTC";

    // Determine greeting based on user time
    const currentHour = DateTime.now().setZone(userTz).hour;
    let greeting = "";
    if (currentHour >= 5 && currentHour < 12) {
      greeting = "Good morning";
    } else if (currentHour >= 12 && currentHour < 17) {
      greeting = "Good afternoon";
    } else if (currentHour >= 17 && currentHour < 22) {
      greeting = "Good evening";
    } else {
      greeting = "Hello";
    }

    const customerName = req.user?.name || req.user?.fullName || req.user?.username || 'Customer';

    const rsearch = req.query.search || ""; // search keyword from query param
    let query = {};

    if (rsearch) {
      query = {
        $or: [
          { cname: { $regex: rsearch, $options: "i" } },
          { review: { $regex: rsearch, $options: "i" } },
        ]
      };
    }

    // find with filter if search provided, else return all
    const reviews = await Review.find(query).sort({ created_at: -1 });

    res.render("edit-reviews", {
      reviews,
      rsearch,
      greeting, 
      customerName // pass search back to EJS so it stays in the box
    });
  } catch (err) {
    console.error(err);
    req.flash("error_msg", "Error fetching reviews");
    res.redirect("/dashboard");
  }
});

// Update code for Reviews
router.post("/reviews/update/:id", upload, async (req, res) => {
  const id = req.params.id;
  let new_image = "";

  if (req.file) {
    new_image = req.file.filename;
    try {
      fs.unlinkSync('./public/uploads/' + req.body.old_image);
    } catch (err) {
      console.error("Error deleting old image:", err);
    }
  } else {
    new_image = req.body.old_image;
  }

  const update = {
    cname: req.body.cname,
    review: req.body.review,
    image: new_image,
  };

  try {
    console.log("Updating review:", update);

    await Review.findByIdAndUpdate(id, update, { new: true });
    req.flash('success_msg', 'Review updated successfully.');
    res.redirect('/edit-reviews'); // correct path
  } catch (err) {
    console.error("Error updating review:", err);
    req.flash('error_msg', 'Failed to update review.');
    res.redirect('/edit-reviews');
  }
});

// Delete code for Reviews
router.get('/reviews/delete/:id', async (req, res) => {
  try {
    const review = await Review.findById(req.params.id);
    if (!review) {
      req.flash('error_msg', 'Review not found');
      return res.redirect('/edit-reviews');
    }

    // Delete image file from disk (optional)
    if (review.image) {
      const imagePath = './public/uploads/' + review.image;
      if (fs.existsSync(imagePath)) {
        fs.unlinkSync(imagePath);
      }
    }

    await Review.findByIdAndDelete(req.params.id);
    req.flash('success_msg', 'Review deleted successfully');
    res.redirect('/edit-reviews');
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error deleting review');
    res.redirect('/edit-reviews');
  }
});


// ==== Reservation List + Search ====
router.get("/edit-reservations", ensureAuthenticated, async (req, res) => {
  try {

     // Get user timezone from cookies or fallback to UTC
    const userTz = req.cookies.timezone || "UTC";

    // Determine greeting based on user time
    const currentHour = DateTime.now().setZone(userTz).hour;
    let greeting = "";
    if (currentHour >= 5 && currentHour < 12) {
      greeting = "Good morning";
    } else if (currentHour >= 12 && currentHour < 17) {
      greeting = "Good afternoon";
    } else if (currentHour >= 17 && currentHour < 22) {
      greeting = "Good evening";
    } else {
      greeting = "Hello";
    }

    const customerName = req.user?.name || req.user?.fullName || req.user?.username || 'Customer';

    const search = req.query.search || ""; // search keyword from query param
    let query = {};

    if (search) {
      query = {
        $or: [
          { fullName: { $regex: search, $options: "i" } },
          { email: { $regex: search, $options: "i" } },
          { phone: { $regex: search, $options: "i" } },
          { date: { $regex: search, $options: "i" } }
        ]
      };
    }

    // find with filter if search provided, else return all
    const reservations = await Reservation.find(query).sort({ created_at: -1 });

    res.render("edit-reservations", {
      reservations,
      search,
      greeting,
      customerName // pass search back to EJS so it stays in the box
    });
  } catch (err) {
    console.error(err);
    req.flash("error_msg", "Error fetching reservations");
    res.redirect("/dashboard");
  }
});

router.post('/reserve', async (req, res) => {
  try {
    const { fullName, phone, email, date, time, guests, description } = req.body;

    const numGuests = parseInt(guests);

    // Step 1: Calculate total guests already reserved for this date & time
    const reservationsAtSlot = await Reservation.find({ date, time });
    const totalGuestsAlready = reservationsAtSlot.reduce((sum, r) => sum + (r.guests || 0), 0);

    // Step 2: Check if adding this reservation exceeds the max
    if (totalGuestsAlready + numGuests > MAX_GUESTS_PER_SLOT) {
      return res.status(400).json({
        message: `Sorry, this time slot is already fully booked. Maximum guests per slot is ${MAX_GUESTS_PER_SLOT}.`,
      });
    }

    // Step 3: Save reservation
    const newReservation = new Reservation({
      fullName,
      phone,
      email,
      date,
      time,
      guests: numGuests,
      description,
    });

    await newReservation.save();

    res.status(200).json({
      message: 'Reservation successful!',
      reservation: newReservation,
    });

  } catch (error) {
    console.error('Error saving reservation:', error.message);
    res.status(500).json({ message: 'Something went wrong. Please try again.' });
  }
});



// This will be used when the Reservation form in modal is submitted
router.post("/reservations/update/:id", upload, async (req, res) => {
  let id = req.params.id;
  
  const update = {
    fullName: req.body.fullName,
    phone: req.body.phone,
    email: req.body.email,
    date: req.body.date,
    time: req.body.time,
    guests: req.body.guests,
    description: req.body.description,
  };

  try {
    await Reservation.findByIdAndUpdate(id, update, { new: true });
    req.flash('success_msg', 'Reservation Updated Successfully..');
    res.redirect('/edit-reservations'); // This will reload your page with updated data
  } catch (err) {
    req.flash('error_msg', 'Unable to update Reservation..');
    res.redirect('/edit-reservations');
  }
});



// Delete code for Reservations
router.get('/reservations/delete/:id', async (req, res) => {
  try {
    const reservation = await Reservation.findById(req.params.id);
    if (!reservation) {
      req.flash('error_msg', 'Reservation not found');
      return res.redirect('/edit-reservations');
    }

    await Reservation.findByIdAndDelete(req.params.id);
    req.flash('success_msg', 'Reservation deleted successfully');
    res.redirect('/edit-reservations');
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error deleting reservation');
    res.redirect('/edit-reservations');
  }
});



/*==== Reservation Search Function ====*/
router.get('/rsearch', async (req, res) => {
  try {
    const search = req.query.wdsearch || "";

    // Build regex
    const regex = new RegExp(search, "i");

    // Search across fields
    const reservations = await Reservation.find({
      $or: [
        { fullName: regex },
        { email: regex },
        { phone: regex },
        { date: regex }
      ]
    });

    // Render results page
    res.render('edit-reservations', { reservations, search });
  } catch (error) {
    console.error(error);
    res.render('edit-reservations', { reservations: [], search: "" });
  }
});

// This code for inserting data will be fetch from here to Index page
router.post('/place-order', async (req, res) => {
    try {
        // console.log("✅ Order received:", req.body); Log entire request
        const order = new Order(req.body);
        await order.save();
        res.status(200).json({ message: "Order placed successfully" });
    } catch (err) {
        console.error("❌ Error saving order:", err);
        res.status(500).json({ message: "Failed to place order" });
    }
});




// Delete code for Orders
router.get('/orders/delete/:id', async (req, res) => {
  try {
    const order = await Order.findById(req.params.id);
    if (!order) {
      req.flash('error_msg', 'Orders not found');
      return res.redirect('/dashboard');
    }

    await Order.findByIdAndDelete(req.params.id);
    req.flash('success_msg', 'Order deleted successfully');
    res.redirect('/dashboard');
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error deleting order');
    res.redirect('/dashboard');
  }
});

// Bill print code for Orders
router.get("/bill/:id", async (req, res) => {
   try {
    const order = await Order.findById(req.params.id).lean();

    if (!order) {
      return res.status(404).send("Order not found");
    }

    const subtotal = order.subtotal || 0;
    const taxAmount = order.tax || 0;

    let discount = 0;
    if (order.offer === "yes") {
      discount = (process.env.OFFER_PERCENTAGE / 100) * subtotal;
    }

    const total = subtotal - discount + taxAmount;

    res.render("receipt", {
      orderId: order._id,
      tableNumber: order.tableNumber,
      items: order.items,
      subtotal,
      discount,
      taxAmount,
      total,
      created_at: order.created_at,
      offerPercent: process.env.OFFER_PERCENTAGE,
    });
  } catch (error) {
    console.error(error);
    res.status(500).send("Server error");
  }
});

// GET /download/orders
router.get('/download/orders', async (req, res) => {
  try {
    const orders = await Order.find().sort({ createdAt: -1 });

    // Create a new workbook and worksheet
    const workbook = new ExcelJS.Workbook();
    const worksheet = workbook.addWorksheet('Orders');

    // Define columns
    worksheet.columns = [
      { header: 'Order ID', key: '_id', width: 25 },
      { header: 'Table Number', key: 'tableNumber', width: 15 },
      { header: 'Offer', key: 'offer', width: 10 },
      { header: 'Items', key: 'items', width: 50 },
      { header: 'Subtotal (₹)', key: 'subtotal', width: 15 },
      { header: 'Tax (₹)', key: 'tax', width: 15 },
      { header: 'Total (₹)', key: 'total', width: 15 },
      { header: 'Created At', key: 'createdAt', width: 25 },
    ];

    // Add rows
    orders.forEach(order => {
      const itemDetails = order.items.map(item => {
        return `${item.name} (x${item.quantity}) - ₹${item.price}`;
      }).join('\n');

      worksheet.addRow({
        _id: order._id.toString(),
        tableNumber: order.tableNumber,
        offer: order.offer,
        items: itemDetails,
        subtotal: order.subtotal,
        tax: order.tax,
        total: order.total,
        createdAt: new Date(order.createdAt).toLocaleString()
      });
    });

    // Set response headers
    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    );
    res.setHeader(
      'Content-Disposition',
      'attachment; filename=orders.xlsx'
    );

    // Write to stream
    await workbook.xlsx.write(res);
    res.end();

  } catch (error) {
    console.error('Error exporting orders to Excel:', error);
    res.status(500).send('Failed to export orders.');
  }
});



router.get('/qr-form', ensureAuthenticated, (req, res) => {

      // Get user timezone from cookies or fallback to UTC
    const userTz = req.cookies.timezone || "UTC";

    // Determine greeting based on user time
    const currentHour = DateTime.now().setZone(userTz).hour;
    let greeting = "";
    if (currentHour >= 5 && currentHour < 12) {
      greeting = "Good morning";
    } else if (currentHour >= 12 && currentHour < 17) {
      greeting = "Good afternoon";
    } else if (currentHour >= 17 && currentHour < 22) {
      greeting = "Good evening";
    } else {
      greeting = "Hello";
    }

    const customerName = req.user?.name || req.user?.fullName || req.user?.username || 'Customer';


  res.render('qr-form',{
    greeting,
    customerName
  });
});

router.post('/generateQR', async (req, res) => {
 try {

    const items = req.body.name.map((name, index) => ({
      name: req.body.name[index],
      sku: req.body.sku[index],
      price: req.body.price[index],
      quantity: req.body.quantity[index],
    }));

    const qrItems = await Promise.all(
      items.map(async (item) => {
        const qrData = JSON.stringify({
          name: item.name,
          sku: item.sku,
          price: item.price
        });

        const qrImage = await QRCode.toDataURL(qrData);

        return {
          ...item,
          qrImage,
        };
      })
    );

    res.render('qr-preview', { 
      qrItems,
      greeting,
      customerName 
    });

  } catch (error) {
    console.error('QR generation error:', error);
    res.status(500).send('QR generation failed.');
  }
});



// ===== SEND OTP FOR LOGIN =====
router.post("/send-login-otp", async (req, res) => {
  try {
    const { email } = req.body;
    const user = await User.findOne({ email });
    if (!user) {
      return res.render("forgot-password", { error_msg: "Email not found!" });
    }

    // Generate 6-digit OTP
    const otp = Math.floor(100000 + Math.random() * 900000).toString();

    // Set OTP expiry 15 min
    user.resetOTP = otp;
    user.resetOTPExpiry = Date.now() + 15 * 60 * 1000;
    await user.save();

    // Send OTP Email
    const html = `<p>Your OTP for login is: <b>${otp}</b></p>`;
    await sendEmail({
      email: user.email,
      subject: "User Login OTP",
      html: html
    });

    // Direct render with message
    res.render("verify-otp-login", { email, success_msg: "OTP sent to your email." });
  } catch (err) {
    console.error(err);
    res.render("forgot-password", { error_msg: "Server error. Try again." });
  }
});

// ===== VERIFY OTP FOR LOGIN =====
router.post("/verify-login-otp", async (req, res, next) => {
  try {
    const { email, otp } = req.body;

    const user = await User.findOne({ email });
    if (!user) {
      req.flash("error_msg", "User not found.");
      return res.redirect("/forgot-password");
    }

    // Expiry check
    if (!user.resetOTPExpiry || Date.now() > new Date(user.resetOTPExpiry).getTime()) {
      req.flash("error_msg", "OTP expired. Please request a new one.");
      return res.redirect("/forgot-password");
    }

    // OTP match
    if (user.resetOTP !== otp) {
      req.flash("error_msg", "Invalid OTP.");
      return res.redirect("/forgot-password");
    }

    // OTP is valid → clear fields
    user.resetOTP = undefined;
    user.resetOTPExpiry = undefined;
    await user.save();

    // ✅ Login user using passport
    req.logIn(user, (err) => {
      if (err) {
        console.error(err);
        req.flash("error_msg", "Login failed after OTP verification.");
        return res.redirect("/signin");
      }

      // Redirect based on role
      const _getRedirectUrl = (req) => {
        if (user.role === "owner") return "/admin-dashboard";
        if (user.role === "admin") return "/dashboard";
        return "/";
      };

      req.flash("success_msg", "OTP verified. Login successful!");
      return res.redirect(_getRedirectUrl(req));
    });
  } catch (err) {
    console.error(err);
    req.flash("error_msg", "Server error. Try again.");
    return res.redirect("/forgot-password");
  }
});


module.exports = router;


