import express from 'express';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';
import multer from 'multer';
import fs from 'fs';
import QRCode from 'qrcode';
import QRCodeSVG from 'qrcode-svg';
import * as XLSX from 'xlsx';

import { hashPassword, verifyPassword, generateToken, authMiddleware, adminMiddleware, restaurantAdminMiddleware } from './auth.js';


dotenv.config();
const module = await import('./database.js');
const { DatabaseService } = module;

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
const PORT = process.env.PORT || 3000;
const db = new DatabaseService();
const upload = multer({
  dest: path.join(__dirname, '..', 'tmp'),
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  },
  fileFilter: (req, file, cb) => {
    if (file.mimetype === 'text/csv' || file.originalname.endsWith('.csv') ||
      file.mimetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
      file.originalname.endsWith('.xlsx')) {
      cb(null, true);
    } else {
      cb(new Error('Only CSV and XLSX files are allowed'));
    }
  }
});
const imageUpload = multer({
  dest: path.join(__dirname, '..', 'tmp'),
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  },
  fileFilter: (req, file, cb) => {
    if (file.mimetype.startsWith('image/')) {
      cb(null, true);
    } else {
      cb(new Error('Only image files are allowed'));
    }
  }
});
function convertXlsxToCsv(filePath) {

  const buffer = fs.readFileSync(filePath);
  const workbook = XLSX.read(buffer, { type: 'buffer' });
  const sheetName = workbook.SheetNames[0]; // Use first sheet
  const worksheet = workbook.Sheets[sheetName];


  const csvContent = XLSX.utils.sheet_to_csv(worksheet);
  return csvContent;
}
function parseCSV(csvContent) {

  if (csvContent.charCodeAt(0) === 0xFEFF) {
    csvContent = csvContent.slice(1);
  }

  const lines = csvContent.split('\n').filter(line => line.trim());
  if (lines.length === 0) return [];


  function parseCSVLine(line) {
    const result = [];
    let current = '';
    let inQuotes = false;

    for (let i = 0; i < line.length; i++) {
      const char = line[i];

      if (char === '"') {
        if (inQuotes && line[i + 1] === '"') {

          current += '"';
          i++; // Skip next quote
        } else {

          inQuotes = !inQuotes;
        }
      } else if (char === ',' && !inQuotes) {

        result.push(current.trim());
        current = '';
      } else {
        current += char;
      }
    }


    result.push(current.trim());
    return result;
  }

  const headers = parseCSVLine(lines[0]);
  const rows = [];

  for (let i = 1; i < lines.length; i++) {
    const values = parseCSVLine(lines[i]);
    if (values.length === headers.length) {
      const row = {};
      headers.forEach((header, index) => {
        row[header] = values[index];
      });
      rows.push(row);
    }
  }

  return rows;
}
app.use(express.json());
app.use(cookieParser());
app.use(cors());
app.use('/static', express.static(path.join(__dirname, '..', 'public', 'static')));
app.use(express.static(path.join(__dirname, '..', 'public')));
app.get('/', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dinerra - Restaurant Menu System</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css" rel="stylesheet">

        <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
        .hero-gradient { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
        
        
        .language-dropdown {
            min-width: 200px;
            box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            animation: dropdownFadeIn 0.15s ease-out;
        }
        
        @keyframes dropdownFadeIn {
            from {
                opacity: 0;
                transform: translateY(-8px) scale(0.95);
            }
            to {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
        }
        
        .language-option {
            transition: all 0.15s ease;
            cursor: pointer;
        }
        
        .language-option:hover {
            background-color: #f9fafb;
            transform: translateX(2px);
        }
        
        .language-option:focus {
            background-color: #f3f4f6;
            outline: 2px solid #4f46e5;
            outline-offset: -2px;
        }
        
        .language-option.selected {
            background-color: #eef2ff;
            color: #4338ca;
            font-weight: 500;
        }
        
        .language-option.selected:hover {
            background-color: #e0e7ff;
        }
        
        .mobile-language-option.selected {
            background-color: #eef2ff;
            color: #4338ca;
            font-weight: 500;
        }
        
        
        @media (prefers-contrast: high) {
            .language-dropdown {
                border: 2px solid #000;
            }
            
            .language-option:focus {
                outline: 3px solid #000;
                background-color: #fff;
            }
        }
        
        
        @media (prefers-reduced-motion: reduce) {
            .language-dropdown {
                animation: none;
            }
            
            .language-option {
                transition: none;
            }
            
            .language-option:hover {
                transform: none;
            }
        }
        
        
        @media (max-width: 768px) {
            .language-dropdown {
                right: 0;
                left: auto;
                min-width: 180px;
            }
        }
        </style>
    </head>
    <body class="bg-gray-50">
        <!-- Navigation -->
        <nav class="bg-white shadow-lg fixed w-full top-0 z-50">
            <div class="max-w-7xl mx-auto px-4">
                <div class="flex justify-between h-16">
                    <div class="flex items-center">
                        <span class="text-2xl font-bold text-indigo-600">Dinerra</span>
                    </div>
                    <div class="hidden md:flex items-center space-x-8">
                        <a href="#pricing" class="text-gray-700 hover:text-indigo-600 transition">Pricing</a>
                        <a href="#about" class="text-gray-700 hover:text-indigo-600 transition">About Us</a>
                        <a href="#contact" class="text-gray-700 hover:text-indigo-600 transition">Contact</a>
                        
                        <!-- Language Selector -->
                        <div id="language-selector" class="relative"></div>
                        
                        <button onclick="openLoginModal()" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition">Login</button>
                    </div>
                    <div class="md:hidden">
                        <button onclick="toggleMobileMenu()" class="text-gray-700 hover:text-indigo-600 transition">
                            <i class="fas fa-bars text-xl"></i>
                        </button>
                    </div>
                </div>
            </div>
        </nav>
        
        <!-- Mobile Menu -->
        <div id="mobileMenu" class="hidden md:hidden bg-white shadow-lg border-t border-gray-200 fixed top-16 left-0 right-0 z-40">
            <div class="px-4 py-2 space-y-1">
                <a href="#pricing" onclick="closeMobileMenu()" class="block px-3 py-2 text-gray-700 hover:text-indigo-600 hover:bg-gray-50 rounded-md transition">Pricing</a>
                <a href="#about" onclick="closeMobileMenu()" class="block px-3 py-2 text-gray-700 hover:text-indigo-600 hover:bg-gray-50 rounded-md transition">About Us</a>
                <a href="#contact" onclick="closeMobileMenu()" class="block px-3 py-2 text-gray-700 hover:text-indigo-600 hover:bg-gray-50 rounded-md transition">Contact</a>
                
                <!-- Mobile Language Selector -->
                <div id="mobile-language-selector" class="px-3 py-2">
                    <label class="block text-xs font-medium text-gray-500 mb-1">Language</label>
                    <div id="mobile-lang-container"></div>
                </div>
                
                <button onclick="openLoginModal(); closeMobileMenu();" class="w-full text-left px-3 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition">Login</button>
            </div>
        </div>

        <!-- Hero Section -->
        <section class="hero-gradient pt-16 pb-20">
            <div class="max-w-7xl mx-auto px-4 pt-16">
                <div class="text-center text-white">
                    <h1 class="text-3xl md:text-5xl font-bold mb-6">Digital Menu Solutions for Modern Restaurants</h1>
                    <p class="text-lg md:text-xl mb-8 opacity-90">Streamline your restaurant operations with our elegant digital menu system</p>
                    <div class="flex flex-col sm:flex-row justify-center space-y-3 sm:space-y-0 sm:space-x-4">
                        <a href="#pricing" class="bg-white text-indigo-600 px-6 md:px-8 py-3 rounded-lg font-semibold hover:bg-gray-100 transition text-center">View Pricing</a>
                        <a href="#contact" class="border border-white text-white px-6 md:px-8 py-3 rounded-lg font-semibold hover:bg-white hover:text-indigo-600 transition text-center">Contact Us</a>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- Pricing Section -->
        <section id="pricing" class="py-20 bg-gray-50 bg-white">
            <div class="max-w-7xl mx-auto px-4">
                <div class="text-center mb-16">
                    <h2 class="text-4xl font-bold text-gray-900 mb-4">Simple, Transparent Pricing</h2>
                    <p class="text-xl text-gray-600">Choose the plan that fits your restaurant's needs</p>
                </div>
                
                <div class="grid md:grid-cols-2 gap-8 max-w-4xl mx-auto">
                    <!-- Monthly Plan -->
                    <div class="bg-white rounded-xl shadow-lg p-8 border-2 border-transparent hover:border-indigo-500 transition">
                        <div class="text-center">
                            <h3 class="text-2xl font-bold text-gray-900 mb-2">Monthly Plan</h3>
                            <p class="text-gray-600 mb-6">Pay monthly, cancel anytime</p>
                            <div class="mb-6">
                                <span class="text-4xl font-bold text-indigo-600">450</span>
                                <span class="text-gray-500"> MKD/month</span>
                            </div>
                            <ul class="text-left space-y-3 mb-8">
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Unlimited menu items</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Advanced customization</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Mobile responsive design</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Analytics dashboard</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Email support</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> No setup fees</li>
                            </ul>
                            <div class="bg-gray-50 p-3 rounded-lg text-sm text-gray-600">
                                Billed monthly • Cancel anytime
                            </div>
                        </div>
                    </div>
                    
                    <!-- Annual Plan -->
                    <div class="bg-white rounded-xl shadow-xl p-8 border-2 border-indigo-500 transform scale-105">
                        <div class="text-center">
                            <div class="bg-indigo-500 text-white px-4 py-1 rounded-full text-sm mb-4">Best Value</div>
                            <h3 class="text-2xl font-bold text-gray-900 mb-2">Annual Plan</h3>
                            <p class="text-gray-600 mb-6">Save 20% with annual payment</p>
                            <div class="mb-6">
                                <div class="flex items-center justify-center">
                                    <span class="text-2xl text-gray-400 line-through mr-2">450</span>
                                    <span class="text-4xl font-bold text-indigo-600">350</span>
                                </div>
                                <span class="text-gray-500"> MKD/month</span>
                                <div class="text-sm text-green-600 font-semibold mt-1">Save 1200 MKD per year!</div>
                            </div>
                            <ul class="text-left space-y-3 mb-8">
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Everything in Monthly Plan</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> 20% discount</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Priority support</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Advanced analytics</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Custom integrations</li>
                                <li class="flex items-center"><i class="fas fa-check text-green-500 mr-2"></i> Dedicated account manager</li>
                            </ul>
                            <div class="bg-green-50 p-3 rounded-lg text-sm text-green-700">
                                Billed annually • 4200 MKD/year
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Contact Section -->
        <section id="contact" class="py-20 bg-gray-50">
            <div class="max-w-7xl mx-auto px-4">
                <div class="text-center mb-16">
                    <h2 class="text-4xl font-bold text-gray-900 mb-4">Contact Us</h2>
                    <p class="text-xl text-gray-600">Get in touch with us about our digital menu solutions</p>
                </div>
                
                <div class="max-w-2xl mx-auto">
                    <div class="bg-white shadow-xl rounded-2xl p-8 border border-gray-100">
                        <form id="contactForm" class="space-y-6">
                            <div class="grid md:grid-cols-2 gap-6">
                                <div>
                                    <label class="block text-sm font-medium text-gray-700 mb-2" for="contact_name">Full Name</label>
                                    <input 
                                        type="text" 
                                        id="contact_name" 
                                        name="name"
                                        required
                                        class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition"
                                        placeholder="Your full name"
                                    >
                                </div>
                                
                                <div>
                                    <label class="block text-sm font-medium text-gray-700 mb-2" for="contact_email">Email Address</label>
                                    <input 
                                        type="email" 
                                        id="contact_email" 
                                        name="email"
                                        required
                                        class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition"
                                        placeholder="your@email.com"
                                    >
                                </div>
                            </div>
                            
                            <div>
                                <label class="block text-sm font-medium text-gray-700 mb-2" for="contact_subject">Subject</label>
                                <select 
                                    id="contact_subject" 
                                    name="subject"
                                    required
                                    class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition"
                                >
                                    <option value="">Select a subject</option>
                                    <option value="General Inquiry">General Inquiry</option>
                                    <option value="Pricing Information">Pricing Information</option>
                                    <option value="Technical Support">Technical Support</option>
                                    <option value="Partnership Opportunities">Partnership Opportunities</option>
                                    <option value="Demo Request">Demo Request</option>
                                </select>
                            </div>
                            
                            <div>
                                <label class="block text-sm font-medium text-gray-700 mb-2" for="contact_message">Message</label>
                                <textarea 
                                    id="contact_message" 
                                    name="message"
                                    rows="5"
                                    required
                                    class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition"
                                    placeholder="Tell us about your restaurant and how we can help..."
                                ></textarea>
                            </div>
                            
                            <button 
                                type="submit" 
                                class="w-full bg-indigo-600 text-white py-3 rounded-lg hover:bg-indigo-700 transition font-semibold flex items-center justify-center"
                            >
                                <i class="fas fa-paper-plane mr-2"></i>Send Message
                            </button>
                        </form>
                        
                        <div id="contactMessage" class="mt-4 hidden"></div>
                        
                        <div class="mt-8 pt-8 border-t border-gray-200 text-center">
                            <div class="grid md:grid-cols-3 gap-6 text-sm text-gray-600">
                                <div class="flex items-center justify-center">
                                    <i class="fas fa-envelope text-indigo-600 mr-2"></i>
                                    <span>info@dinerra.com</span>
                                </div>
                                <div class="flex items-center justify-center">
                                    <i class="fas fa-clock text-indigo-600 mr-2"></i>
                                    <span>24/7 Support</span>
                                </div>
                                <div class="flex items-center justify-center">
                                    <i class="fas fa-reply text-indigo-600 mr-2"></i>
                                    <span>Quick Response</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        <!-- About Section -->
        <section id="about" class="py-20 bg-white">
            <div class="max-w-7xl mx-auto px-4">
                <div class="text-center mb-16">
                    <h2 class="text-4xl font-bold text-gray-900 mb-4">About Dinerra</h2>
                    <p class="text-xl text-gray-600">Revolutionizing restaurant menu management</p>
                </div>
                
                <div class="grid md:grid-cols-2 gap-12 items-center">
                    <div>
                        <h3 class="text-2xl font-bold text-gray-900 mb-6">Our Mission</h3>
                        <p class="text-gray-600 mb-6">
                            We believe every restaurant deserves a beautiful, functional digital menu that enhances the dining experience. 
                            Our platform helps restaurants of all sizes create stunning digital menus that work seamlessly across all devices.
                        </p>
                        <div class="space-y-4">
                            <div class="flex items-center">
                                <i class="fas fa-mobile-alt text-indigo-600 text-xl mr-4"></i>
                                <span class="text-gray-700">Mobile-first design for modern diners</span>
                            </div>
                            <div class="flex items-center">
                                <i class="fas fa-palette text-indigo-600 text-xl mr-4"></i>
                                <span class="text-gray-700">Customizable themes to match your brand</span>
                            </div>
                            <div class="flex items-center">
                                <i class="fas fa-chart-line text-indigo-600 text-xl mr-4"></i>
                                <span class="text-gray-700">Analytics to understand customer preferences</span>
                            </div>
                        </div>
                    </div>
                    <div class="bg-gradient-to-br from-indigo-500 to-purple-600 rounded-2xl p-8 text-white">
                        <div class="text-center">
                            <i class="fas fa-utensils text-6xl mb-6 opacity-80"></i>
                            <h4 class="text-2xl font-bold mb-4">Trusted by 1000+ Restaurants</h4>
                            <p class="opacity-90">From small cafes to large restaurant chains, Dinerra powers digital menus worldwide</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Login Modal -->
        <div id="loginModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
            <div class="relative top-4 md:top-20 mx-auto p-5 border w-11/12 max-w-md shadow-lg rounded-md bg-white">
                <div class="mt-3 text-center">
                    <div class="flex justify-between items-center mb-4">
                        <h3 class="text-lg font-medium text-gray-900">Restaurant Login</h3>
                        <button onclick="closeLoginModal()" class="text-gray-400 hover:text-gray-600">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <p class="text-sm text-gray-500 mb-6">Access your menu dashboard</p>
                    
                    <form id="loginForm" class="space-y-4">
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-2" for="email">Email Address</label>
                            <input 
                                type="email" 
                                id="email" 
                                required
                                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
                                placeholder="Enter your email"
                            >
                        </div>
                        
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-2" for="password">Password</label>
                            <input 
                                type="password" 
                                id="password" 
                                required
                                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
                                placeholder="Enter your password"
                            >
                        </div>
                        
                        <button 
                            type="submit" 
                            class="w-full bg-indigo-600 text-white py-2 rounded-md hover:bg-indigo-700 transition font-medium"
                        >
                            <i class="fas fa-sign-in-alt mr-2"></i>Sign In to Dashboard
                        </button>
                    </form>
                    
                    <div class="mt-4 text-center">
                        <button 
                            onclick="showForgotPassword()"
                            class="text-sm text-indigo-600 hover:text-indigo-500 transition"
                        >
                            <i class="fas fa-key mr-1"></i>Forgot Password?
                        </button>
                    </div>
                    
                    <div id="message" class="mt-4 hidden"></div>
                </div>
            </div>
        </div>

        <!-- Forgot Password Modal -->
        <div id="forgotPasswordModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
            <div class="relative top-4 md:top-20 mx-auto p-5 border w-11/12 max-w-md shadow-lg rounded-md bg-white">
                <div class="mt-3 text-center">
                    <div class="flex justify-between items-center mb-4">
                        <h3 class="text-lg font-medium text-gray-900">Reset Password</h3>
                        <button onclick="closeForgotPasswordModal()" class="text-gray-400 hover:text-gray-600">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <p class="text-sm text-gray-500 mb-6">Enter your email to receive password reset instructions</p>
                    
                    <form id="forgotPasswordForm" class="space-y-4">
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-2" for="forgotEmail">Email Address</label>
                            <input 
                                type="email" 
                                id="forgotEmail" 
                                required
                                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
                                placeholder="Enter your email address"
                            >
                        </div>
                        
                        <button 
                            type="submit" 
                            class="w-full bg-indigo-600 text-white py-2 rounded-md hover:bg-indigo-700 transition font-medium"
                        >
                            <i class="fas fa-paper-plane mr-2"></i>Send Reset Instructions
                        </button>
                    </form>
                    
                    <div class="mt-4 text-center">
                        <button 
                            onclick="showLogin()"
                            class="text-sm text-indigo-600 hover:text-indigo-500 transition"
                        >
                            <i class="fas fa-arrow-left mr-1"></i>Back to Login
                        </button>
                    </div>
                    
                    <div id="forgotMessage" class="mt-4 hidden"></div>
                </div>
            </div>
        </div>

        <!-- Footer -->
        <footer class="bg-gray-900 text-white py-12">
            <div class="max-w-7xl mx-auto px-4 text-center">
                <div class="mb-8">
                    <span class="text-3xl font-bold">Dinerra</span>
                    <p class="text-gray-400 mt-2">Digital Menu Solutions for Modern Restaurants</p>
                </div>
                <div class="flex justify-center space-x-8 text-sm">
                    <a href="#" class="text-gray-400 hover:text-white transition">Privacy Policy</a>
                    <a href="#" class="text-gray-400 hover:text-white transition">Terms of Service</a>
                    <a href="#" class="text-gray-400 hover:text-white transition">Contact Support</a>
                </div>
                <p class="text-gray-400 text-sm mt-8">&copy; 2024 Dinerra. All rights reserved.</p>
            </div>
        </footer>
        
        <script src="https://cdn.jsdelivr.net/npm/axios@1.6.0/dist/axios.min.js"></script>
        <script src="/static/language-selector.js"></script>
        <script>
            function openLoginModal() {
                document.getElementById('loginModal').classList.remove('hidden');
                document.body.classList.add('overflow-hidden');
            }
            
            function closeLoginModal() {
                document.getElementById('loginModal').classList.add('hidden');
                document.body.classList.remove('overflow-hidden');
            }

            function showForgotPassword() {
                document.getElementById('loginModal').classList.add('hidden');
                document.getElementById('forgotPasswordModal').classList.remove('hidden');
                document.body.classList.add('overflow-hidden');
            }

            function closeForgotPasswordModal() {
                document.getElementById('forgotPasswordModal').classList.add('hidden');
                document.body.classList.remove('overflow-hidden');
            }

            function showLogin() {
                document.getElementById('forgotPasswordModal').classList.add('hidden');
                document.getElementById('loginModal').classList.remove('hidden');
                document.body.classList.add('overflow-hidden');
            }
            

            function toggleMobileMenu() {
                const menu = document.getElementById('mobileMenu');
                menu.classList.toggle('hidden');
            }
            
            function closeMobileMenu() {
                document.getElementById('mobileMenu').classList.add('hidden');
            }
            

            document.getElementById('loginModal').addEventListener('click', function(e) {
                if (e.target === this) {
                    closeLoginModal();
                }
            });

            document.getElementById('forgotPasswordModal').addEventListener('click', function(e) {
                if (e.target === this) {
                    closeForgotPasswordModal();
                }
            });
            

            document.addEventListener('click', function(e) {
                const menu = document.getElementById('mobileMenu');
                const menuButton = e.target.closest('button[onclick="toggleMobileMenu()"]');
                if (!menu.contains(e.target) && !menuButton && !menu.classList.contains('hidden')) {
                    closeMobileMenu();
                }
            });
            

            document.querySelectorAll('a[href^="#"]').forEach(anchor => {
                anchor.addEventListener('click', function (e) {
                    e.preventDefault();
                    const target = document.querySelector(this.getAttribute('href'));
                    if (target) {
                        target.scrollIntoView({
                            behavior: 'smooth'
                        });
                    }
                });
            });
            document.getElementById('contactForm').addEventListener('submit', async (e) => {
                e.preventDefault();
                
                const formData = new FormData(e.target);
                const contactData = {
                    name: formData.get('name'),
                    email: formData.get('email'),
                    subject: formData.get('subject'),
                    message: formData.get('message')
                };
                
                const messageDiv = document.getElementById('contactMessage');
                const submitBtn = e.target.querySelector('button[type="submit"]');
                

                submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>Sending...';
                submitBtn.disabled = true;
                
                try {
                    const response = await axios.post('/api/contact', contactData);
                    
                    if (response.data.success) {
                        messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg';
                        messageDiv.textContent = 'Thank you! Your message has been sent successfully. We will get back to you soon.';
                        messageDiv.classList.remove('hidden');
                        

                        e.target.reset();
                    }
                } catch (error) {
                    messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg';
                    messageDiv.textContent = error.response?.data?.message || 'Failed to send message. Please try again.';
                    messageDiv.classList.remove('hidden');
                } finally {

                    submitBtn.innerHTML = '<i class="fas fa-paper-plane mr-2"></i>Send Message';
                    submitBtn.disabled = false;
                }
            });
            document.getElementById('loginForm').addEventListener('submit', async (e) => {
                e.preventDefault();
                
                const email = document.getElementById('email').value;
                const password = document.getElementById('password').value;
                const messageDiv = document.getElementById('message');
                
                try {
                    const response = await axios.post('/api/auth/login', { email, password });
                    
                    if (response.data.success) {
                        localStorage.setItem('token', response.data.token);
                        localStorage.setItem('user', JSON.stringify(response.data.user));
                        
                        messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg';
                        messageDiv.textContent = 'Login successful! Redirecting...';
                        messageDiv.classList.remove('hidden');
                        
                        setTimeout(() => {
                            window.location.href = '/admin/dashboard';
                        }, 1500);
                    }
                } catch (error) {
                    messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg';
                    messageDiv.textContent = error.response?.data?.message || 'Login failed. Please try again.';
                    messageDiv.classList.remove('hidden');
                }
            });
            document.getElementById('forgotPasswordForm').addEventListener('submit', async (e) => {
                e.preventDefault();
                
                const email = document.getElementById('forgotEmail').value;
                const messageDiv = document.getElementById('forgotMessage');
                const submitBtn = e.target.querySelector('button[type="submit"]');
                

                submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>Sending...';
                submitBtn.disabled = true;
                
                try {
                    const response = await axios.post('/api/auth/forgot-password', { email });
                    
                    messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg';
                    messageDiv.textContent = response.data.message || 'Password reset instructions sent to your email.';
                    messageDiv.classList.remove('hidden');
                    

                    e.target.reset();
                } catch (error) {
                    messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg';
                    messageDiv.textContent = error.response?.data?.message || 'Failed to send reset instructions. Please try again.';
                    messageDiv.classList.remove('hidden');
                } finally {

                    submitBtn.innerHTML = '<i class="fas fa-paper-plane mr-2"></i>Send Reset Instructions';
                    submitBtn.disabled = false;
                }
            });
            

            

        </script>
    </body>
    </html>
  `);
});

app.get('/menu/:restaurantSlug', async (req, res) => {
  try {
    const restaurantSlug = req.params.restaurantSlug;


    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).send(`
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Restaurant Not Found</title>
            <script src="https://cdn.tailwindcss.com"></script>
        </head>
        <body class="bg-gray-50 flex items-center justify-center min-h-screen">
            <div class="text-center">
                <div class="mb-4">
                    <i class="fas fa-exclamation-triangle text-6xl text-yellow-500"></i>
                </div>
                <h1 class="text-3xl font-bold text-gray-900 mb-2">Restaurant Not Found</h1>
                <p class="text-gray-600 mb-6">The restaurant you're looking for doesn't exist.</p>
                <a href="/" class="bg-indigo-600 text-white px-6 py-3 rounded-lg hover:bg-indigo-700 transition">
                    Go Back Home
                </a>
            </div>
        </body>
        </html>
      `);
    }

    if (!restaurant.is_active) {
      return res.status(403).send(`
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Restaurant Unavailable</title>
            <script src="https://cdn.tailwindcss.com"></script>
        </head>
        <body class="bg-gray-50 flex items-center justify-center min-h-screen">
            <div class="text-center">
                <div class="mb-4">
                    <i class="fas fa-ban text-6xl text-red-500"></i>
                </div>
                <h1 class="text-3xl font-bold text-gray-900 mb-2">Restaurant Unavailable</h1>
                <p class="text-gray-600 mb-6">This restaurant's menu is currently unavailable.</p>
                <a href="/" class="bg-indigo-600 text-white px-6 py-3 rounded-lg hover:bg-indigo-700 transition">
                    Go Back Home
                </a>
            </div>
        </body>
        </html>
      `);
    }

  } catch (error) {
    console.error('Error checking restaurant status:', error);
    return res.status(500).send(`
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Error</title>
          <script src="https://cdn.tailwindcss.com"></script>
      </head>
      <body class="bg-gray-50 flex items-center justify-center min-h-screen">
          <div class="text-center">
              <div class="mb-4">
                  <i class="fas fa-exclamation-circle text-6xl text-red-500"></i>
              </div>
              <h1 class="text-3xl font-bold text-gray-900 mb-2">Something went wrong</h1>
              <p class="text-gray-600 mb-6">Please try again later.</p>
              <a href="/" class="bg-indigo-600 text-white px-6 py-3 rounded-lg hover:bg-indigo-700 transition">
                  Go Back Home
              </a>
          </div>
      </body>
      </html>
    `);
  }

  const restaurantSlug = req.params.restaurantSlug;
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Restaurant Menu</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css" rel="stylesheet">
        <script>
            tailwind.config = {
                theme: {
                    extend: {
                        colors: {
                            'brand-orange': '#f97316',
                            'brand-red': '#dc2626'
                        }
                    }
                }
            }
            window.restaurantSlug = '${restaurantSlug}';
        </script>
    </head>
    <body class="bg-gray-50 min-h-screen">
        <!-- Fixed Header -->
        <header class="bg-white shadow-sm border-b border-gray-200 fixed top-0 left-0 right-0 z-50">
            <div class="max-w-7xl mx-auto px-4">
                <div class="flex justify-between items-center h-16">
                    <!-- Logo/Home Link -->
                    <div class="flex items-center">
                        <div class="flex items-center text-gray-800">
                            <i class="fas fa-utensils text-xl mr-2"></i>
                            <span class="font-semibold">Menu</span>
                        </div>
                    </div>
                    
                    <!-- Right Side: Language Selector and Cart -->
                    <div class="flex items-center space-x-4">
                        <!-- Language Selector -->
                        <div id="language-selector" class="relative"></div>
                        
                        <!-- Cart Button -->
                        <button onclick="app && app.toggleCart()" class="relative bg-brand-orange text-white px-4 py-2 rounded-lg hover:bg-orange-600 transition-colors">
                            <i class="fas fa-shopping-cart mr-2"></i>
                            <span class="hidden sm:inline">Cart</span>
                            <span id="cart-count" class="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center min-w-[20px]" style="display: none;">0</span>
                        </button>
                    </div>
                </div>
                
                <!-- Mobile Menu Button (hidden for now, can be added later) -->
                <div class="md:hidden" style="display: none;">
                    <button onclick="toggleMobileMenu()" class="text-gray-700 hover:text-brand-orange transition">
                        <i class="fas fa-bars text-xl"></i>
                    </button>
                </div>
            </div>
        </header>
        
        <!-- Mobile Menu (hidden for now) -->
        <div id="mobileMenu" class="hidden md:hidden bg-white shadow-lg border-t border-gray-200 fixed top-16 left-0 right-0 z-40">
            <div class="px-4 py-2 space-y-1">
                <!-- Mobile Language Selector -->
                <div id="mobile-language-selector" class="px-3 py-2">
                    <label class="block text-xs font-medium text-gray-500 mb-1">Language</label>
                    <div id="mobile-lang-container"></div>
                </div>
            </div>
        </div>
        
        <!-- Main Content (with top padding for fixed header) -->
        <div id="app" class="pt-16">
            <div class="text-center py-8">
                <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-brand-orange mx-auto"></div>
                <p class="mt-4 text-gray-600">Loading menu...</p>
            </div>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/axios@1.6.0/dist/axios.min.js"></script>
        <script src="/static/language-selector.js"></script>
        <script src="/static/menu.js"></script>
    </body>
    </html>
  `);
});
app.get('/reset-password', (req, res) => {
  const token = req.query.token;
  if (!token) {
    return res.status(400).send('Invalid reset token');
  }

  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Reset Password - Restaurant Menu System</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css" rel="stylesheet">
    </head>
    <body class="bg-gray-100 min-h-screen flex items-center justify-center">
        <div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
            <div class="text-center mb-6">
                <h1 class="text-2xl font-bold text-gray-900">Reset Password</h1>
                <p class="text-gray-600 mt-2">Enter your new password</p>
            </div>
            
            <form id="resetPasswordForm">
                <input type="hidden" id="token" value="${token}">
                
                <div class="mb-4">
                    <label class="block text-gray-700 text-sm font-bold mb-2" for="newPassword">
                        New Password
                    </label>
                    <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" 
                           id="newPassword" type="password" placeholder="Enter new password" required minlength="6">
                </div>
                
                <div class="mb-6">
                    <label class="block text-gray-700 text-sm font-bold mb-2" for="confirmPassword">
                        Confirm Password
                    </label>
                    <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" 
                           id="confirmPassword" type="password" placeholder="Confirm new password" required minlength="6">
                </div>
                
                <div class="flex items-center justify-center">
                    <button class="bg-orange-600 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" 
                            type="submit">
                        <i class="fas fa-key mr-2"></i>Reset Password
                    </button>
                </div>
            </form>
            
            <div id="message" class="mt-4 hidden"></div>
            
            <div class="text-center mt-6">
                <a href="/admin" class="text-blue-600 hover:text-blue-800 text-sm">
                    <i class="fas fa-arrow-left mr-1"></i>Back to Login
                </a>
            </div>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/axios@1.6.0/dist/axios.min.js"></script>
        <script>
            document.getElementById('resetPasswordForm').addEventListener('submit', async (e) => {
                e.preventDefault();
                
                const token = document.getElementById('token').value;
                const newPassword = document.getElementById('newPassword').value;
                const confirmPassword = document.getElementById('confirmPassword').value;
                const messageDiv = document.getElementById('message');
                
                if (newPassword !== confirmPassword) {
                    messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg';
                    messageDiv.textContent = 'Passwords do not match';
                    messageDiv.classList.remove('hidden');
                    return;
                }
                
                try {
                    const response = await axios.post('/api/auth/reset-password-with-token', {
                        token: token,
                        newPassword: newPassword
                    });
                    
                    if (response.data.success) {
                        messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg';
                        messageDiv.textContent = 'Password reset successfully! You can now login with your new password.';
                        messageDiv.classList.remove('hidden');
                        
                        setTimeout(() => {
                            window.location.href = '/admin';
                        }, 2000);
                    }
                } catch (error) {
                    messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg';
                    messageDiv.textContent = error.response?.data?.message || 'Password reset failed. Please try again.';
                    messageDiv.classList.remove('hidden');
                }
            });
        </script>
    </body>
    </html>
  `);
});
app.get('/admin', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Admin Login - Restaurant Menu System</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css" rel="stylesheet">
    </head>
    <body class="bg-gray-100 min-h-screen flex items-center justify-center">
        <div class="max-w-md w-full bg-white rounded-lg shadow-md p-6">
            <div class="text-center mb-8">
                <h1 class="text-2xl font-bold text-gray-900 mb-2">
                    <i class="fas fa-utensils mr-2 text-orange-600"></i>
                    Restaurant Admin
                </h1>
                <p class="text-gray-600">Sign in to manage your menu</p>
            </div>
            
            <form id="loginForm">
                <div class="mb-4">
                    <label class="block text-gray-700 text-sm font-bold mb-2" for="email">
                        Email
                    </label>
                    <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" 
                           id="email" type="email" placeholder="Enter your email" required>
                </div>
                <div class="mb-6">
                    <label class="block text-gray-700 text-sm font-bold mb-2" for="password">
                        Password
                    </label>
                    <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" 
                           id="password" type="password" placeholder="Enter your password" required>
                </div>
                <div class="flex items-center justify-between">
                    <button class="bg-orange-600 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full" 
                            type="submit">
                        <i class="fas fa-sign-in-alt mr-2"></i>Sign In
                    </button>
                </div>
            </form>
            
            <div class="text-center mt-4">
                <button id="forgotPasswordBtn" class="text-blue-600 hover:text-blue-800 text-sm">
                    Forgot Password?
                </button>
            </div>
            
            <div id="message" class="mt-4 hidden"></div>
            
            <!-- Forgot Password Modal -->
            <div id="forgotPasswordModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden">
                <div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
                    <div class="mt-3 text-center">
                        <h3 class="text-lg font-medium text-gray-900">Forgot Password</h3>
                        <div class="mt-2 px-7 py-3">
                            <p class="text-sm text-gray-500">Enter your email address and we'll send you a link to reset your password.</p>
                        </div>
                        <form id="forgotPasswordForm" class="mt-4">
                            <input type="email" id="forgotEmail" placeholder="Enter your email" 
                                   class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" 
                                   required>
                        </form>
                        <div class="items-center px-4 py-3">
                            <button id="sendResetLink" 
                                    class="px-4 py-2 bg-blue-600 text-white text-base font-medium rounded-md w-full shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-300">
                                Send Reset Link
                            </button>
                        </div>
                        <div class="items-center px-4 py-3">
                            <button id="closeForgotModal" 
                                    class="px-4 py-2 bg-gray-300 text-gray-800 text-base font-medium rounded-md w-full shadow-sm hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-300">
                                Cancel
                            </button>
                        </div>
                        <div id="forgotMessage" class="mt-2 hidden"></div>
                    </div>
                </div>
            </div>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/axios@1.6.0/dist/axios.min.js"></script>
        <script src="/static/admin-login.js"></script>
    </body>
    </html>
  `);
});
app.get('/admin/dashboard', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Admin Dashboard - Restaurant Menu System</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css" rel="stylesheet">
    </head>
    <body class="bg-gray-100">
        <div id="app">
            <div class="text-center py-8">
                <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-orange-600 mx-auto"></div>
                <p class="mt-4 text-gray-600">Loading dashboard...</p>
            </div>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/axios@1.6.0/dist/axios.min.js"></script>

        <script src="/static/admin-dashboard.js"></script>
    </body>
    </html>
  `);
});
app.get('/api/init-db', async (req, res) => {
  try {
    await db.initTables();
    res.json({ success: true, message: 'Database initialized successfully' });
  } catch (error) {
    console.error('Error initializing database:', error);
    res.status(500).json({ success: false, message: 'Failed to initialize database', error: error.message });
  }
});
app.get('/api/hash/:password', async (req, res) => {
  try {
    const password = req.params.password;
    const hash = await hashPassword(password);
    res.json({ success: true, password, hash });
  } catch (error) {
    res.json({ success: false, error: error.message });
  }
});
app.get('/api/seed-db', async (req, res) => {
  try {
    await db.seedDatabase();
    res.json({ success: true, message: 'Database seeded successfully' });
  } catch (error) {
    console.error('Error seeding database:', error);
    res.status(500).json({ success: false, message: 'Failed to seed database', error: error.message });
  }
});
app.get('/api/restaurants', async (req, res) => {
  try {
    const restaurants = await db.getAllRestaurants();
    res.json({ success: true, data: restaurants });
  } catch (error) {
    console.error('Error fetching restaurants:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch restaurants' });
  }
});
app.get('/api/restaurants/:id', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    res.json({ success: true, data: restaurant });
  } catch (error) {
    console.error('Error fetching restaurant:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch restaurant' });
  }
});
app.get('/api/restaurants/slug/:slug', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    res.json({ success: true, data: restaurant });
  } catch (error) {
    console.error('Error fetching restaurant:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch restaurant' });
  }
});
app.get('/api/restaurants/:id/category-types', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const categoryTypes = await db.getCategoryTypesByRestaurant(restaurantId);
    res.json({ success: true, data: categoryTypes });
  } catch (error) {
    console.error('Error fetching category types:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch category types' });
  }
});
app.get('/api/restaurants/slug/:slug/category-types', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const categoryTypes = await db.getCategoryTypesByRestaurant(restaurant.id);
    res.json({ success: true, data: categoryTypes });
  } catch (error) {
    console.error('Error fetching category types:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch category types' });
  }
});
app.get('/api/restaurants/:id/categories', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const type = req.query.type;
    const categories = await db.getCategoriesByRestaurant(restaurantId, type);
    res.json({ success: true, data: categories });
  } catch (error) {
    console.error('Error fetching categories:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch categories' });
  }
});
app.get('/api/restaurants/slug/:slug/categories', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const type = req.query.type;
    const categories = await db.getCategoriesByRestaurant(restaurant.id, type);
    res.json({ success: true, data: categories });
  } catch (error) {
    console.error('Error fetching categories:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch categories' });
  }
});
app.get('/api/categories/:categoryId/next-order', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const categoryId = parseInt(req.params.categoryId);
    const nextOrder = await db.getNextDisplayOrder(categoryId);
    res.json({ success: true, data: { next_order: nextOrder } });
  } catch (error) {
    console.error('Error getting next display order:', error);
    res.status(500).json({ success: false, message: 'Failed to get next display order' });
  }
});
app.get('/api/categories/:id/items', async (req, res) => {
  try {
    const categoryId = parseInt(req.params.id);
    const items = await db.getMenuItemsByCategory(categoryId);
    res.json({ success: true, data: items });
  } catch (error) {
    console.error('Error fetching menu items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch menu items' });
  }
});
app.post('/api/contact', async (req, res) => {
  try {
    const { name, email, subject, message } = req.body;


    if (!name || !email || !subject || !message) {
      return res.status(400).json({ success: false, message: 'All fields are required' });
    }


    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return res.status(400).json({ success: false, message: 'Please provide a valid email address' });
    }

    console.log('Contact Form Submission:', {
      name,
      email,
      subject,
      message,
      timestamp: new Date().toISOString()
    });


    res.json({
      success: true,
      message: 'Thank you for your message! We will get back to you within 24 hours.'
    });
  } catch (error) {
    console.error('Error processing contact form:', error);
    res.status(500).json({ success: false, message: 'Failed to send message. Please try again.' });
  }
});

app.post('/api/auth/login', async (req, res) => {
  try {
    const { email, password } = req.body;

    const user = await db.getUserByEmail(email);
    if (!user) {
      return res.status(401).json({ success: false, message: 'Invalid credentials' });
    }

    const isValidPassword = await verifyPassword(password, user.password_hash);
    if (!isValidPassword) {
      return res.status(401).json({ success: false, message: 'Invalid credentials' });
    }

    const token = generateToken(user);

    res.json({
      success: true,
      token,
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
        role: user.role,
        restaurant_id: user.restaurant_id,
        must_change_password: user.must_change_password
      }
    });
  } catch (error) {
    console.error('Login error:', error);
    res.status(500).json({ success: false, message: 'Login failed' });
  }
});
app.post('/api/auth/reset-password', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const { userId } = req.body;

    if (!userId) {
      return res.status(400).json({ success: false, message: 'User ID is required' });
    }
    const user = await db.getUserById(userId);
    if (!user) {
      return res.status(404).json({ success: false, message: 'User not found' });
    }
    const hashedPassword = await hashPassword(user.email);
    const success = await db.updateUserPasswordWithFlags(userId, hashedPassword, true);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Password reset failed' });
    }

    res.json({
      success: true,
      message: `Password reset successfully. User must login with email (${user.email}) as password and change it on first login.`
    });
  } catch (error) {
    console.error('Password reset error:', error);
    res.status(500).json({ success: false, message: 'Password reset failed' });
  }
});
app.post('/api/auth/forgot-password', async (req, res) => {
  try {
    const { email } = req.body;

    if (!email) {
      return res.status(400).json({ success: false, message: 'Email is required' });
    }


    const user = await db.getUserByEmail(email);
    if (!user) {

      return res.json({ success: true, message: 'If the email exists, a reset link has been sent.' });
    }


    const resetToken = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
    const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour from now


    await db.createPasswordResetToken(email, resetToken, expiresAt);


    const resetLink = `${req.protocol}://${req.get('host')}/reset-password?token=${resetToken}`;
    console.log('Password reset link for', email, ':', resetLink);

    res.json({
      success: true,
      message: 'If the email exists, a reset link has been sent.',

      resetLink: resetLink
    });
  } catch (error) {
    console.error('Forgot password error:', error);
    res.status(500).json({ success: false, message: 'Failed to process forgot password request' });
  }
});
app.post('/api/auth/reset-password-with-token', async (req, res) => {
  try {
    const { token, newPassword } = req.body;

    if (!token || !newPassword) {
      return res.status(400).json({ success: false, message: 'Token and new password are required' });
    }


    const resetToken = await db.getPasswordResetToken(token);
    if (!resetToken) {
      return res.status(400).json({ success: false, message: 'Invalid or expired reset token' });
    }


    const user = await db.getUserByEmail(resetToken.email);
    if (!user) {
      return res.status(400).json({ success: false, message: 'User not found' });
    }


    const hashedPassword = await hashPassword(newPassword);
    await db.updateUserPasswordWithFlags(user.id, hashedPassword, false);


    await db.usePasswordResetToken(token);

    res.json({ success: true, message: 'Password reset successfully' });
  } catch (error) {
    console.error('Password reset error:', error);
    res.status(500).json({ success: false, message: 'Password reset failed' });
  }
});
app.post('/api/auth/change-password', authMiddleware, async (req, res) => {
  try {
    const { currentPassword, newPassword } = req.body;
    const user = req.user;

    if (!newPassword) {
      return res.status(400).json({ success: false, message: 'New password is required' });
    }


    const fullUser = await db.getUserById(user.id);
    if (!fullUser) {
      return res.status(400).json({ success: false, message: 'User not found' });
    }

    if (!fullUser.must_change_password && currentPassword) {
      const isValidPassword = await verifyPassword(currentPassword, fullUser.password_hash);
      if (!isValidPassword) {
        return res.status(400).json({ success: false, message: 'Current password is incorrect' });
      }
    }


    const hashedPassword = await hashPassword(newPassword);
    await db.updateUserPasswordWithFlags(user.id, hashedPassword, false);

    res.json({ success: true, message: 'Password changed successfully' });
  } catch (error) {
    console.error('Change password error:', error);
    res.status(500).json({ success: false, message: 'Password change failed' });
  }
});
app.post('/api/admin/users', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const userData = req.body;


    const existingUser = await db.getUserByEmail(userData.email);
    if (existingUser) {
      return res.status(400).json({ success: false, message: 'Email already exists' });
    }


    if (!userData.password) {
      return res.status(400).json({ success: false, message: 'Password is required' });
    }

    const hashedPassword = await hashPassword(userData.password);
    const userId = await db.createUser({
      ...userData,
      password_hash: hashedPassword,
      must_change_password: false // No need to force password change when admin sets it
    });

    res.json({ success: true, data: { id: userId } });
  } catch (error) {
    console.error('Error creating user:', error);
    res.status(500).json({ success: false, message: 'Failed to create user' });
  }
});
app.get('/api/admin/users', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const users = await db.getAllUsers();

    const safeUsers = users.map(user => ({
      ...user,
      password_hash: undefined
    }));
    res.json({ success: true, data: safeUsers });
  } catch (error) {
    console.error('Error fetching users:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch users' });
  }
});
app.put('/api/admin/users/:id/status', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const userId = parseInt(req.params.id);
    const { is_active } = req.body;

    const success = await db.updateUserStatus(userId, is_active);

    if (!success) {
      return res.status(404).json({ success: false, message: 'User not found' });
    }

    res.json({ success: true, message: 'User status updated successfully' });
  } catch (error) {
    console.error('Error updating user status:', error);
    res.status(500).json({ success: false, message: 'Failed to update user status' });
  }
});
app.delete('/api/admin/users/:id', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const userId = parseInt(req.params.id);
    const success = await db.deleteUser(userId);

    if (!success) {
      return res.status(404).json({ success: false, message: 'User not found' });
    }

    res.json({ success: true, message: 'User deleted successfully' });
  } catch (error) {
    console.error('Error deleting user:', error);
    res.status(500).json({ success: false, message: 'Failed to delete user' });
  }
});
app.post('/api/admin/restaurants', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const restaurantData = req.body;

    // Create restaurant-specific upload directory
    if (restaurantData.slug) {
      const restaurantUploadDir = path.join(__dirname, '..', 'public', 'uploads', restaurantData.slug);
      if (!fs.existsSync(restaurantUploadDir)) {
        fs.mkdirSync(restaurantUploadDir, { recursive: true });
      }
    }

    const restaurantId = await db.createRestaurant(restaurantData);


    try {
      const restaurant = await db.getRestaurantById(restaurantId);
      const logoPath = restaurant.logo_url ?
        path.join(__dirname, '..', 'public', restaurant.logo_url) : null;

      const qrResult = await generateQRCode(restaurant.slug, logoPath);


      await db.updateRestaurant(restaurantId, {
        ...restaurant,
        qr_code_url: qrResult.url, // Legacy field
        qr_svg_path: qrResult.svgPath,
        qr_png_path: qrResult.pngPath,
        qr_target_url: qrResult.targetUrl
      });

      res.json({
        success: true,
        data: {
          id: restaurantId,
          qr_code_url: qrResult.url, // Legacy field
          qr_svg_path: qrResult.svgPath,
          qr_png_path: qrResult.pngPath,
          qr_target_url: qrResult.targetUrl
        }
      });
    } catch (qrError) {
      console.error('Error generating QR code:', qrError);

      res.json({
        success: true,
        data: { id: restaurantId },
        warning: 'Restaurant created but QR code generation failed'
      });
    }
  } catch (error) {
    console.error('Error creating restaurant:', error);

    // Handle specific slug duplication error
    if (error.message === 'SLUG_ALREADY_EXISTS') {
      return res.status(400).json({
        success: false,
        message: 'This slug is already taken. Please choose a different one.',
        error: 'SLUG_ALREADY_EXISTS'
      });
    }

    res.status(500).json({ success: false, message: 'Failed to create restaurant' });
  }
});
app.put('/api/admin/restaurants/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurantData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    // If logo_url is being updated or removed, delete the old logo file
    if (restaurantData.hasOwnProperty('logo_url')) {
      const oldRestaurant = await db.getRestaurantById(restaurantId);
      if (oldRestaurant && oldRestaurant.logo_url && oldRestaurant.logo_url !== restaurantData.logo_url) {
        // Delete old logo file
        const oldLogoPath = path.join(__dirname, '..', 'public', oldRestaurant.logo_url);
        if (fs.existsSync(oldLogoPath)) {
          try {
            fs.unlinkSync(oldLogoPath);
            console.log(`Deleted old logo: ${oldLogoPath}`);
          } catch (err) {
            console.error(`Error deleting old logo: ${err.message}`);
          }
        }
      }
    }

    const success = await db.updateRestaurant(restaurantId, restaurantData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    res.json({ success: true, message: 'Restaurant updated successfully' });
  } catch (error) {
    console.error('Error updating restaurant:', error);
    res.status(500).json({ success: false, message: 'Failed to update restaurant' });
  }
});
app.put('/api/admin/restaurants/:id/status', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const { is_active, only_restaurant } = req.body;

    const success = await db.updateRestaurantStatus(restaurantId, is_active, only_restaurant);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    res.json({ success: true, message: 'Restaurant status updated successfully' });
  } catch (error) {
    console.error('Error updating restaurant status:', error);
    res.status(500).json({ success: false, message: 'Failed to update restaurant status' });
  }
});
app.put('/api/admin/restaurants/:id/hot-items-settings', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const {
      hot_items_label_mk,
      hot_items_label_en,
      hot_items_label_al,
      hot_items_description_mk,
      hot_items_description_en,
      hot_items_description_al
    } = req.body;

    // Prepare update data
    const hotItemsData = {
      hot_items_label_mk: hot_items_label_mk || null,
      hot_items_label_en: hot_items_label_en || null,
      hot_items_label_al: hot_items_label_al || null,
      hot_items_description_mk: hot_items_description_mk || null,
      hot_items_description_en: hot_items_description_en || null,
      hot_items_description_al: hot_items_description_al || null,
      // Set the main label based on priority: mk > en > al
      hot_items_label: hot_items_label_mk || hot_items_label_en || hot_items_label_al || 'Hot Items',
      hot_items_description: hot_items_description_mk || hot_items_description_en || hot_items_description_al || null
    };

    const success = await db.updateRestaurant(restaurantId, hotItemsData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    res.json({ success: true, message: 'Hot items settings updated successfully' });
  } catch (error) {
    console.error('Error updating hot items settings:', error);
    res.status(500).json({ success: false, message: 'Failed to update hot items settings' });
  }
});
app.post('/api/admin/restaurants/deactivate-expired', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const deactivatedCount = await db.deactivateExpiredRestaurants();

    res.json({
      success: true,
      message: `Auto-deactivated ${deactivatedCount} expired restaurants`,
      deactivated_count: deactivatedCount
    });
  } catch (error) {
    console.error('Error auto-deactivating expired restaurants:', error);
    res.status(500).json({ success: false, message: 'Failed to auto-deactivate expired restaurants' });
  }
});
app.delete('/api/admin/restaurants/:id', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);


    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }


    const success = await db.deleteRestaurant(restaurantId);

    if (!success) {
      return res.status(500).json({ success: false, message: 'Failed to delete restaurant from database' });
    }


    try {
      const qrCodeDir = path.join(__dirname, '..', 'public', 'qrcodes', restaurant.slug);
      if (fs.existsSync(qrCodeDir)) {

        const files = fs.readdirSync(qrCodeDir);
        files.forEach(file => {
          const filePath = path.join(qrCodeDir, file);
          if (fs.existsSync(filePath)) {
            fs.unlinkSync(filePath);
          }
        });


        fs.rmdirSync(qrCodeDir);
        console.log(`QR code directory deleted: ${qrCodeDir}`);
      }
    } catch (qrDeleteError) {
      console.error('Error deleting QR code files:', qrDeleteError);

    }


    try {
      if (restaurant.logo_url) {
        const logoPath = path.join(__dirname, '..', 'public', restaurant.logo_url);
        if (fs.existsSync(logoPath)) {
          fs.unlinkSync(logoPath);
          console.log(`Restaurant logo deleted: ${logoPath}`);
        }
      }
    } catch (logoDeleteError) {
      console.error('Error deleting restaurant logo:', logoDeleteError);

    }

    res.json({
      success: true,
      message: 'Restaurant and associated files deleted successfully',
      data: {
        restaurant_id: restaurantId,
        restaurant_name: restaurant.name,
        restaurant_slug: restaurant.slug
      }
    });
  } catch (error) {
    console.error('Error deleting restaurant:', error);
    res.status(500).json({ success: false, message: 'Failed to delete restaurant' });
  }
});
app.get('/api/admin/restaurants/:id/category-types', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const categoryTypes = await db.getCategoryTypesForAdmin(restaurantId);
    res.json({ success: true, data: categoryTypes });
  } catch (error) {
    console.error('Error fetching category types:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch category types' });
  }
});
app.post('/api/admin/category-types', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const typeData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== typeData.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const typeId = await db.createCategoryType(typeData);
    res.json({ success: true, data: { id: typeId } });
  } catch (error) {
    console.error('Error creating category type:', error);
    if (error.code === 'ER_DUP_ENTRY') {
      res.status(400).json({ success: false, message: 'Category type already exists for this restaurant' });
    } else {
      res.status(500).json({ success: false, message: 'Failed to create category type' });
    }
  }
});
app.delete('/api/admin/category-types/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const typeId = parseInt(req.params.id);

    const success = await db.deleteCategoryType(typeId);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category type not found' });
    }

    res.json({ success: true, message: 'Category type deleted successfully' });
  } catch (error) {
    console.error('Error deleting category type:', error);
    res.status(500).json({ success: false, message: 'Failed to delete category type' });
  }
});
app.put('/api/admin/category-types/order', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const { types } = req.body;

    const success = await db.updateCategoryTypeOrder(types);

    if (!success) {
      return res.status(400).json({ success: false, message: 'Failed to update category type order' });
    }

    res.json({ success: true, message: 'Category type order updated successfully' });
  } catch (error) {
    console.error('Error updating category type order:', error);
    res.status(500).json({ success: false, message: 'Failed to update category type order' });
  }
});
app.put('/api/admin/category-types/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const typeId = parseInt(req.params.id);
    const typeData = req.body;

    const success = await db.updateCategoryType(typeId, typeData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category type not found or no changes made' });
    }

    res.json({ success: true, message: 'Category type updated successfully' });
  } catch (error) {
    console.error('Error updating category type:', error);
    res.status(500).json({ success: false, message: 'Failed to update category type' });
  }
});
app.get('/api/admin/restaurants/:id/categories', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const type = req.query.type;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const categories = await db.getCategoriesForAdmin(restaurantId, type);
    res.json({ success: true, data: categories });
  } catch (error) {
    console.error('Error fetching categories for admin:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch categories' });
  }
});
app.post('/api/admin/categories', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const categoryData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== categoryData.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const categoryId = await db.createCategory({
      ...categoryData,
      display_order: categoryData.display_order || 0
    });

    res.json({ success: true, data: { id: categoryId } });
  } catch (error) {
    console.error('Error creating category:', error);
    res.status(500).json({ success: false, message: 'Failed to create category' });
  }
});
app.put('/api/admin/categories/order', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const { categories } = req.body;

    const success = await db.updateCategoryOrder(categories);

    if (!success) {
      return res.status(400).json({ success: false, message: 'Failed to update category order' });
    }

    res.json({ success: true, message: 'Category order updated successfully' });
  } catch (error) {
    console.error('Error updating category order:', error);
    res.status(500).json({ success: false, message: 'Failed to update category order' });
  }
});
app.put('/api/admin/categories/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const categoryId = parseInt(req.params.id);
    const categoryData = req.body;

    const success = await db.updateCategory(categoryId, categoryData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category not found' });
    }

    res.json({ success: true, message: 'Category updated successfully' });
  } catch (error) {
    console.error('Error updating category:', error);
    res.status(500).json({ success: false, message: 'Failed to update category' });
  }
});
app.delete('/api/admin/categories/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const categoryId = parseInt(req.params.id);
    const success = await db.deleteCategory(categoryId);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category not found' });
    }

    res.json({ success: true, message: 'Category deleted successfully' });
  } catch (error) {
    console.error('Error deleting category:', error);
    res.status(500).json({ success: false, message: 'Failed to delete category' });
  }
});
app.post('/api/admin/menu-items', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const itemData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== itemData.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const itemId = await db.createMenuItem({
      ...itemData,
      display_order: itemData.display_order || 0
    });

    res.json({ success: true, data: { id: itemId } });
  } catch (error) {
    console.error('Error creating menu item:', error);
    res.status(500).json({ success: false, message: 'Failed to create menu item' });
  }
});
app.put('/api/admin/menu-items/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const itemId = parseInt(req.params.id);
    const itemData = req.body;

    // If image_url is being updated or removed, delete the old image file
    if (itemData.hasOwnProperty('image_url')) {
      const oldItem = await db.getMenuItemById(itemId);
      if (oldItem && oldItem.image_url && oldItem.image_url !== itemData.image_url) {
        // Delete old image file
        const oldImagePath = path.join(__dirname, '..', 'public', oldItem.image_url);
        if (fs.existsSync(oldImagePath)) {
          try {
            fs.unlinkSync(oldImagePath);
            console.log(`Deleted old image: ${oldImagePath}`);
          } catch (err) {
            console.error(`Error deleting old image: ${err.message}`);
          }
        }
      }
    }

    const success = await db.updateMenuItem(itemId, itemData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Menu item not found' });
    }

    res.json({ success: true, message: 'Menu item updated successfully' });
  } catch (error) {
    console.error('Error updating menu item:', error);
    res.status(500).json({ success: false, message: 'Failed to update menu item' });
  }
});
app.post('/api/admin/menu-items/bulk-price-update', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const { updates } = req.body; // Array of {id, price}
    const user = req.user;

    if (!Array.isArray(updates) || updates.length === 0) {
      return res.status(400).json({ success: false, message: 'Updates array is required' });
    }

    let successCount = 0;
    let errors = [];

    for (const update of updates) {
      try {
        const itemId = parseInt(update.id);
        const newPrice = parseFloat(update.price);

        if (isNaN(itemId) || isNaN(newPrice) || newPrice < 0) {
          errors.push(`Invalid data for item ID ${update.id}`);
          continue;
        }

        // Verify item belongs to user's restaurant
        const item = await db.getMenuItemById(itemId);
        if (!item) {
          errors.push(`Item ID ${itemId} not found`);
          continue;
        }

        if (user.role === 'restaurant_admin' && user.restaurant_id !== item.restaurant_id) {
          errors.push(`Access denied for item ID ${itemId}`);
          continue;
        }

        // Update only the price
        const success = await db.updateMenuItem(itemId, { price: newPrice });
        if (success) {
          successCount++;
        } else {
          errors.push(`Failed to update item ID ${itemId}`);
        }
      } catch (error) {
        console.error(`Error updating item ${update.id}:`, error);
        errors.push(`Item ${update.id}: ${error.message}`);
      }
    }

    res.json({
      success: true,
      message: `Updated ${successCount} items successfully`,
      details: {
        updated: successCount,
        total: updates.length,
        errors: errors
      }
    });
  } catch (error) {
    console.error('Error in bulk price update:', error);
    res.status(500).json({ success: false, message: 'Failed to update prices: ' + error.message });
  }
});
app.delete('/api/admin/menu-items/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const itemId = parseInt(req.params.id);

    // Get menu item to delete its image file
    const item = await db.getMenuItemById(itemId);
    if (item && item.image_url) {
      // Delete image file
      const imagePath = path.join(__dirname, '..', 'public', item.image_url);
      if (fs.existsSync(imagePath)) {
        try {
          fs.unlinkSync(imagePath);
          console.log(`Deleted image: ${imagePath}`);
        } catch (err) {
          console.error(`Error deleting image: ${err.message}`);
        }
      }
    }

    const success = await db.deleteMenuItem(itemId);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Menu item not found' });
    }

    res.json({ success: true, message: 'Menu item deleted successfully' });
  } catch (error) {
    console.error('Error deleting menu item:', error);
    res.status(500).json({ success: false, message: 'Failed to delete menu item' });
  }
});
app.post('/api/admin/menu-items/:id/duplicate', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const itemId = parseInt(req.params.id);
    const newItemId = await db.duplicateMenuItem(itemId);

    if (!newItemId) {
      return res.status(404).json({ success: false, message: 'Menu item not found' });
    }

    res.json({ success: true, data: { id: newItemId }, message: 'Menu item duplicated successfully' });
  } catch (error) {
    console.error('Error duplicating menu item:', error);
    res.status(500).json({ success: false, message: 'Failed to duplicate menu item' });
  }
});
app.get('/api/admin/restaurants/:id/menu-items', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }


    const categoryFilter = req.query.categories;
    let categoryIds = null;

    if (categoryFilter) {
      categoryIds = categoryFilter.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
    }

    const items = await db.getMenuItemsByRestaurantForAdmin(restaurantId, categoryIds);
    res.json({ success: true, data: items });
  } catch (error) {
    console.error('Error fetching menu items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch menu items' });
  }
});
app.get('/api/admin/total-menu-items', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const totalCount = await db.getTotalMenuItemsCount();
    res.json({ success: true, data: totalCount });
  } catch (error) {
    console.error('Error fetching total menu items count:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch total menu items count' });
  }
});
app.get('/api/admin/restaurants/:id/promotions', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const promotions = await db.getPromotionsByRestaurant(restaurantId);
    res.json({ success: true, data: promotions });
  } catch (error) {
    console.error('Error fetching promotions:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch promotions' });
  }
});
app.get('/api/admin/promotions/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const promotionId = parseInt(req.params.id);
    const promotion = await db.getPromotionById(promotionId);

    if (!promotion) {
      return res.status(404).json({ success: false, message: 'Promotion not found' });
    }

    res.json({ success: true, data: promotion });
  } catch (error) {
    console.error('Error fetching promotion:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch promotion' });
  }
});
app.post('/api/admin/promotions', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const promotionData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin') {
      promotionData.restaurant_id = user.restaurant_id;
    }

    const promotionId = await db.createPromotion(promotionData);
    res.status(201).json({
      success: true,
      message: 'Promotion created successfully',
      data: { id: promotionId }
    });
  } catch (error) {
    console.error('Error creating promotion:', error);
    res.status(500).json({ success: false, message: 'Failed to create promotion' });
  }
});
app.put('/api/admin/promotions/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const promotionId = parseInt(req.params.id);
    const promotionData = req.body;

    const success = await db.updatePromotion(promotionId, promotionData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Promotion not found' });
    }

    res.json({ success: true, message: 'Promotion updated successfully' });
  } catch (error) {
    console.error('Error updating promotion:', error);
    res.status(500).json({ success: false, message: 'Failed to update promotion' });
  }
});
app.delete('/api/admin/promotions/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const promotionId = parseInt(req.params.id);
    const success = await db.deletePromotion(promotionId);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Promotion not found' });
    }

    res.json({ success: true, message: 'Promotion deleted successfully' });
  } catch (error) {
    console.error('Error deleting promotion:', error);
    res.status(500).json({ success: false, message: 'Failed to delete promotion' });
  }
});
app.put('/api/admin/promotions/:id/order', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const promotionId = parseInt(req.params.id);
    const { display_order } = req.body;

    const success = await db.updatePromotionOrder(promotionId, display_order);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Promotion not found' });
    }

    res.json({ success: true, message: 'Promotion order updated successfully' });
  } catch (error) {
    console.error('Error updating promotion order:', error);
    res.status(500).json({ success: false, message: 'Failed to update promotion order' });
  }
});
app.get('/api/restaurants/:id/promotions', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const promotions = await db.getVisiblePromotionsByRestaurant(restaurantId);
    res.json({ success: true, data: promotions });
  } catch (error) {
    console.error('Error fetching visible promotions:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch promotions' });
  }
});
app.get('/api/restaurants/slug/:slug/promotions', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const promotions = await db.getVisiblePromotionsByRestaurant(restaurant.id);
    res.json({ success: true, data: promotions });
  } catch (error) {
    console.error('Error fetching visible promotions:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch promotions' });
  }
});
app.get('/api/restaurants/:id/sale-items', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const saleItems = await db.getSaleItemsByRestaurant(restaurantId);
    res.json({ success: true, data: saleItems });
  } catch (error) {
    console.error('Error fetching sale items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch sale items' });
  }
});
app.get('/api/restaurants/slug/:slug/sale-items', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const saleItems = await db.getSaleItemsByRestaurant(restaurant.id);
    res.json({ success: true, data: saleItems });
  } catch (error) {
    console.error('Error fetching sale items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch sale items' });
  }
});
app.post('/api/admin/category-types/:restaurantId/:typeName/sale', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.restaurantId);
    const categoryTypeName = req.params.typeName;
    const saleData = req.body;
    const user = req.user;


    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }


    if (saleData.is_on_sale && (!saleData.sale_type || !saleData.sale_value)) {
      return res.status(400).json({
        success: false,
        message: 'Sale type and value are required when setting sale'
      });
    }

    const success = await db.setSaleByCategoryType(restaurantId, categoryTypeName, saleData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category type not found' });
    }

    res.json({ success: true, message: 'Sale updated successfully for category type and all items' });
  } catch (error) {
    console.error('Error setting category type sale:', error);
    res.status(500).json({ success: false, message: 'Failed to set category type sale' });
  }
});
app.post('/api/admin/categories/:categoryId/sale', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const categoryId = parseInt(req.params.categoryId);
    const saleData = req.body;
    const user = req.user;


    const category = await db.getCategoryById(categoryId);

    if (!category) {
      return res.status(404).json({ success: false, message: 'Category not found' });
    }


    if (user.role === 'restaurant_admin' && user.restaurant_id !== category.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }


    if (saleData.is_on_sale && (!saleData.sale_type || !saleData.sale_value)) {
      return res.status(400).json({
        success: false,
        message: 'Sale type and value are required when setting sale'
      });
    }

    const success = await db.setSaleByCategory(category.restaurant_id, categoryId, saleData);

    if (!success) {
      return res.status(404).json({ success: false, message: 'Category not found' });
    }

    res.json({ success: true, message: 'Sale updated successfully for category and all items' });
  } catch (error) {
    console.error('Error setting category sale:', error);
    res.status(500).json({ success: false, message: 'Failed to set category sale' });
  }
});
app.post('/api/upload/:type/:slug?', authMiddleware, imageUpload.single('image'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ success: false, message: 'No image file provided' });
    }

    const uploadType = req.params.type; // restaurants, menu-items, users
    const restaurantSlug = req.params.slug;
    const validTypes = ['restaurants', 'menu-items', 'users'];

    if (!validTypes.includes(uploadType)) {
      return res.status(400).json({ success: false, message: 'Invalid upload type' });
    }

    // Get optional naming parameters from request body
    const itemNameEn = req.body.item_name_en; // For menu items
    const isLogo = req.body.is_logo === 'true' || req.body.is_logo === true; // For restaurant logos

    // For menu-items, require restaurant slug and create folder structure
    let uploadDir;
    let imageUrl;

    if (uploadType === 'menu-items' && restaurantSlug) {
      // Validate slug format
      if (!/^[a-z0-9-]+$/.test(restaurantSlug)) {
        return res.status(400).json({ success: false, message: 'Invalid restaurant slug format' });
      }
      uploadDir = path.join(__dirname, '..', 'public', 'uploads', 'menu-items', restaurantSlug);
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true });
      }
      const fileExtension = path.extname(req.file.originalname);

      // Use item name_en if provided, otherwise use timestamp
      let fileName;
      if (itemNameEn && itemNameEn.trim()) {
        // Sanitize the name_en to be filesystem-safe
        const sanitizedName = itemNameEn.trim()
          .toLowerCase()
          .replace(/[^a-z0-9]+/g, '-')
          .replace(/^-+|-+$/g, '');
        fileName = `${sanitizedName}${fileExtension}`;
      } else {
        fileName = `${Date.now()}-${Math.random().toString(36).substring(7)}${fileExtension}`;
      }

      const finalPath = path.join(uploadDir, fileName);
      fs.renameSync(req.file.path, finalPath);
      imageUrl = `/uploads/menu-items/${restaurantSlug}/${fileName}`;
    } else if (uploadType === 'restaurants') {
      // For restaurant logos
      uploadDir = path.join(__dirname, '..', 'public', 'uploads', uploadType);
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true });
      }
      const fileExtension = path.extname(req.file.originalname);

      // Use 'restaurant-logo' if it's a logo, otherwise use timestamp
      let fileName;
      if (isLogo) {
        fileName = `restaurant-logo${fileExtension}`;
      } else {
        fileName = `${Date.now()}-${Math.random().toString(36).substring(7)}${fileExtension}`;
      }

      const finalPath = path.join(uploadDir, fileName);
      fs.renameSync(req.file.path, finalPath);
      imageUrl = `/uploads/${uploadType}/${fileName}`;
    } else {
      // Default behavior for other types
      uploadDir = path.join(__dirname, '..', 'public', 'uploads', uploadType);
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true });
      }
      const fileExtension = path.extname(req.file.originalname);
      const uniqueName = `${Date.now()}-${Math.random().toString(36).substring(7)}${fileExtension}`;
      const finalPath = path.join(uploadDir, uniqueName);
      fs.renameSync(req.file.path, finalPath);
      imageUrl = `/uploads/${uploadType}/${uniqueName}`;
    }

    res.json({
      success: true,
      data: {
        url: imageUrl,
        filename: path.basename(imageUrl)
      }
    });
  } catch (error) {
    console.error('Error uploading image:', error);


    if (req.file && req.file.path && fs.existsSync(req.file.path)) {
      try {
        fs.unlinkSync(req.file.path);
      } catch (cleanupError) {
        console.error('Error cleaning up temp file:', cleanupError);
      }
    }

    res.status(500).json({ success: false, message: 'Failed to upload image' });
  }
});
app.post('/api/upload/restaurants/:slug', authMiddleware, imageUpload.single('image'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ success: false, message: 'No image file provided' });
    }

    const restaurantSlug = req.params.slug;
    const isLogo = req.body.is_logo === 'true' || req.body.is_logo === true;


    if (!/^[a-z0-9-]+$/.test(restaurantSlug)) {
      return res.status(400).json({ success: false, message: 'Invalid restaurant slug format' });
    }
    const restaurantUploadDir = path.join(__dirname, '..', 'public', 'uploads', restaurantSlug);
    if (!fs.existsSync(restaurantUploadDir)) {
      fs.mkdirSync(restaurantUploadDir, { recursive: true });
    }
    const fileExtension = path.extname(req.file.originalname);

    // Use 'restaurant-logo' if it's a logo, otherwise use timestamp
    let fileName;
    if (isLogo) {
      fileName = `restaurant-logo${fileExtension}`;
    } else {
      fileName = `logo-${Date.now()}-${Math.random().toString(36).substring(7)}${fileExtension}`;
    }

    const finalPath = path.join(restaurantUploadDir, fileName);
    fs.renameSync(req.file.path, finalPath);
    const imageUrl = `/uploads/${restaurantSlug}/${fileName}`;

    res.json({
      success: true,
      data: {
        url: imageUrl,
        filename: fileName,
        slug: restaurantSlug
      }
    });
  } catch (error) {
    console.error('Error uploading restaurant logo:', error);


    if (req.file && req.file.path && fs.existsSync(req.file.path)) {
      try {
        fs.unlinkSync(req.file.path);
      } catch (cleanupError) {
        console.error('Error cleaning up temp file:', cleanupError);
      }
    }

    res.status(500).json({ success: false, message: 'Failed to upload restaurant logo' });
  }
});
app.delete('/api/upload/:type/:filename', authMiddleware, async (req, res) => {
  try {
    const { type, filename } = req.params;
    const validTypes = ['restaurants', 'menu-items', 'users'];

    if (!validTypes.includes(type)) {
      return res.status(400).json({ success: false, message: 'Invalid upload type' });
    }

    const filePath = path.join(__dirname, '..', 'public', 'uploads', type, filename);

    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
      res.json({ success: true, message: 'Image deleted successfully' });
    } else {
      res.status(404).json({ success: false, message: 'Image not found' });
    }
  } catch (error) {
    console.error('Error deleting image:', error);
    res.status(500).json({ success: false, message: 'Failed to delete image' });
  }
});
app.post('/api/admin/upload-excel', authMiddleware, restaurantAdminMiddleware, upload.single('excelFile'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ success: false, message: 'No Excel file provided' });
    }

    const user = req.user;
    const { restaurantId } = req.body;

    if (!restaurantId) {
      return res.status(400).json({ success: false, message: 'Restaurant ID is required' });
    }
    if (user.role === 'restaurant_admin' && user.restaurant_id !== parseInt(restaurantId)) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }
    const isXlsxFile = req.file.originalname.toLowerCase().endsWith('.xlsx') ||
      req.file.mimetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';

    if (!isXlsxFile) {
      return res.status(400).json({ success: false, message: 'Only Excel (.xlsx) files are allowed' });
    }
    const buffer = fs.readFileSync(req.file.path);
    const workbook = XLSX.read(buffer, { type: 'buffer' });


    const requiredSheets = ['Types', 'Categories', 'Menu Items'];
    const missingSheets = requiredSheets.filter(sheet => !workbook.SheetNames.includes(sheet));

    if (missingSheets.length > 0) {
      return res.status(400).json({
        success: false,
        message: `Missing required sheets: ${missingSheets.join(', ')}. Please use the provided template.`
      });
    }
    const result = await processExcelData(db, workbook, parseInt(restaurantId));
    fs.unlinkSync(req.file.path);

    res.json({
      success: true,
      message: 'Excel data imported successfully',
      processedCount: result.created + result.updated,
      details: {
        created: result.created,
        updated: result.updated,
        errors: result.errors,
        skipped: result.skipped
      }
    });
  } catch (error) {

    if (req.file && fs.existsSync(req.file.path)) {
      fs.unlinkSync(req.file.path);
    }
    console.error('Error uploading Excel:', error);
    res.status(500).json({ success: false, message: 'Failed to upload Excel file: ' + error.message });
  }
});
app.post('/api/admin/upload-csv', authMiddleware, restaurantAdminMiddleware, upload.single('csvFile'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ success: false, message: 'No CSV or XLSX file provided' });
    }

    const { dataType, restaurantId, overrideMenu } = req.body;
    const user = req.user;

    if (!dataType || !restaurantId) {
      return res.status(400).json({ success: false, message: 'Data type and restaurant ID are required' });
    }
    if (user.role === 'restaurant_admin' && user.restaurant_id !== parseInt(restaurantId)) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }
    let csvContent;
    const isXlsxFile = req.file.originalname.toLowerCase().endsWith('.xlsx') ||
      req.file.mimetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';

    try {
      if (isXlsxFile) {

        console.log('Processing XLSX file...');
        csvContent = convertXlsxToCsv(req.file.path);
      } else {

        const buffer = fs.readFileSync(req.file.path);


        if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {

          csvContent = buffer.toString('utf8');
        } else if (buffer[0] === 0xFF && buffer[1] === 0xFE) {

          csvContent = buffer.toString('utf16le');
        } else if (buffer[0] === 0xFE && buffer[1] === 0xFF) {

          csvContent = buffer.toString('utf16be');
        } else {

          csvContent = buffer.toString('utf8');
        }
      }
    } catch (error) {
      console.error('Error processing file:', error);
      throw new Error('Failed to process uploaded file. Please ensure it is a valid CSV or XLSX file.');
    }

    const rows = parseCSV(csvContent);

    let result;


    if (dataType !== 'unified') {
      return res.status(400).json({ success: false, message: 'Only unified CSV format is supported' });
    }


    const shouldOverride = overrideMenu === 'true' || overrideMenu === true || overrideMenu === undefined;

    result = await uploadSimplifiedCSV(db, rows, parseInt(restaurantId), shouldOverride);
    fs.unlinkSync(req.file.path);

    res.json({
      success: true,
      message: shouldOverride
        ? `Successfully replaced entire menu with ${result.created} items.`
        : `Successfully processed ${result.created} items. ${result.skipped} duplicates skipped.`,
      processedCount: result.created,
      skippedCount: result.skipped,
      overridden: shouldOverride,
      details: result
    });
  } catch (error) {

    if (req.file && fs.existsSync(req.file.path)) {
      fs.unlinkSync(req.file.path);
    }
    console.error('Error uploading CSV/XLSX:', error);
    res.status(500).json({ success: false, message: 'Failed to upload file: ' + error.message });
  }
});
app.get('/api/admin/download-template', authMiddleware, restaurantAdminMiddleware, (req, res) => {
  try {

    const templateData = [
      ['type', 'category', 'name', 'description', 'price', 'size_info', 'allergens'],
      ['Food', '', '', '', '', '', ''],
      ['', 'Breakfast', '', '', '', '', ''],
      ['', '', 'Pancakes', 'Fluffy breakfast pancakes', '8.50', '3 pieces', 'Gluten, Eggs, Milk'],
      ['', '', 'Omelet', 'Ham, cheese, mushrooms', '12.00', '300g', 'Eggs'],
      ['', 'Main Course', '', '', '', '', ''],
      ['', '', 'Grilled Salmon', 'Fresh salmon with herbs', '18.50', '200g', 'Fish'],
      ['', '', 'Chicken Parmesan', 'Breaded chicken with cheese', '15.50', '250g', 'Gluten, Dairy'],
      ['', 'Appetizers', '', '', '', '', ''],
      ['', '', 'Caesar Salad', 'Fresh romaine with Caesar dressing', '8.50', '300g', 'Gluten, Dairy, Eggs'],
      ['', '', 'Bruschetta', 'Toasted bread with tomatoes', '6.00', '4 pieces', 'Gluten'],
      ['Drinks', '', '', '', '', '', ''],
      ['', 'Hot Drinks', '', '', '', '', ''],
      ['', '', 'Espresso', 'Strong aromatic coffee', '2.50', '50ml', ''],
      ['', '', 'Cappuccino', 'Espresso with steamed milk foam', '3.50', '200ml', 'Milk'],
      ['', '', 'Americano', 'Espresso with hot water', '2.80', '250ml', ''],
      ['', 'Cold Drinks', '', '', '', '', ''],
      ['', '', 'Coca Cola', 'Classic soda', '3.00', '330ml', ''],
      ['', '', 'Orange Juice', 'Fresh squeezed juice', '4.00', '250ml', ''],
      ['', '', 'Iced Coffee', 'Cold brew coffee', '4.50', '300ml', ''],
      ['', 'Alcoholic', '', '', '', '', ''],
      ['', '', 'House Wine', 'Red or white', '12.00', '150ml', 'Sulphites'],
      ['', '', 'Draft Beer', 'Local lager', '5.50', '500ml', ''],
      ['Desserts', '', '', '', '', '', ''],
      ['', 'Sweet Treats', '', '', '', '', ''],
      ['', '', 'Chocolate Cake', 'Rich dark chocolate layer cake', '6.00', '150g', 'Gluten, Dairy, Eggs'],
      ['', '', 'Tiramisu', 'Classic Italian coffee dessert', '7.50', '120g', 'Gluten, Dairy, Eggs, Alcohol']
    ];
    const workbook = XLSX.utils.book_new();
    const worksheet = XLSX.utils.aoa_to_sheet(templateData);
    worksheet['!cols'] = [
      { wch: 15 }, // type
      { wch: 15 }, // category
      { wch: 20 }, // name
      { wch: 40 }, // description
      { wch: 10 }, // price
      { wch: 12 }, // size_info
      { wch: 25 }  // allergens
    ];
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Menu Template');
    const xlsxBuffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });

    const filename = 'restaurant_template.xlsx';

    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);

    res.send(xlsxBuffer);
  } catch (error) {
    console.error('Error generating template:', error);
    res.status(500).json({ success: false, message: 'Failed to generate template' });
  }
});
async function generateQRCode(restaurantSlug, logoPath = null, options = {}) {

  let domain = process.env.DOMAIN;
  if (!domain) {
    domain = process.env.NODE_ENV === 'production' ? 'your-domain.com' : 'localhost:3000';
  }


  domain = domain.replace(/^https?:\/\//, '');

  const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http';
  const qrUrl = `${protocol}://${domain}/menu/${restaurantSlug}`;

  console.log(`Generating QR code for: ${qrUrl}`);
  console.log(`QR Code options:`, JSON.stringify(options, null, 2));


  const qrCodeDir = path.join(__dirname, '..', 'public', 'qrcodes', restaurantSlug);
  if (!fs.existsSync(qrCodeDir)) {
    fs.mkdirSync(qrCodeDir, { recursive: true });
  }


  const qrOptions = options.qrOptions || {};
  const colorOptions = qrOptions.color || {};
  const logoOptions = qrOptions.logo || {};
  const width = options.width || 512;
  const height = options.height || 512;
  const margin = options.margin || 1;
  const errorCorrection = options.errorCorrectionLevel || 'M';
  const includeLogo = options.includeLogo && logoPath && fs.existsSync(logoPath);

  console.log(`QR Code Generation - includeLogo: ${options.includeLogo}, logoPath: ${logoPath}, fileExists: ${logoPath ? fs.existsSync(logoPath) : false}, finalIncludeLogo: ${includeLogo}`);


  let darkColor = colorOptions.dark || '#000000';
  let lightColor = colorOptions.light || '#FFFFFF';


  const qrSvg = new QRCodeSVG({
    content: qrUrl,
    padding: margin,
    width: width,
    height: height,
    color: darkColor,
    background: lightColor,
    ecl: errorCorrection
  });


  const svgFilename = `qr.svg`;
  const svgPath = path.join(qrCodeDir, svgFilename);
  let svgContent = qrSvg.svg();




  if (qrOptions.dotStyle === 'round') {
    svgContent = svgContent.replace(/<rect([^>]*width="1"[^>]*)/g, '<circle$1 r="0.5"');
  } else if (qrOptions.dotStyle === 'rounded') {
    svgContent = svgContent.replace(/<rect/g, '<rect rx="0.2"');
  }


  if (includeLogo && fs.existsSync(logoPath)) {
    try {
      const logoSize = logoOptions.size || 20; // percentage of QR size
      const logoSizePx = (width * logoSize) / 100;
      const logoX = (width - logoSizePx) / 2;
      const logoY = (height - logoSizePx) / 2;


      const logoBuffer = fs.readFileSync(logoPath);
      const logoExt = path.extname(logoPath).toLowerCase();
      const logoMimeType = logoExt === '.png' ? 'image/png' : logoExt === '.jpg' || logoExt === '.jpeg' ? 'image/jpeg' : 'image/png';
      const logoBase64 = logoBuffer.toString('base64');
      const logoDataUrl = `data:${logoMimeType};base64,${logoBase64}`;


      let logoElement = '';
      if (logoOptions.background) {
        const bgSize = logoSizePx * 1.2;
        const bgX = (width - bgSize) / 2;
        const bgY = (height - bgSize) / 2;
        const borderRadius = logoOptions.borderRadius || 8;

        logoElement += `<rect x="${bgX}" y="${bgY}" width="${bgSize}" height="${bgSize}" fill="${logoOptions.backgroundColor || '#ffffff'}" rx="${borderRadius}" ry="${borderRadius}"/>`;
      }

      logoElement += `<image x="${logoX}" y="${logoY}" width="${logoSizePx}" height="${logoSizePx}" href="${logoDataUrl}"/>`;


      svgContent = svgContent.replace('</svg>', `${logoElement}</svg>`);

      console.log(`Added logo to SVG QR code: ${logoPath}`);
    } catch (logoError) {
      console.error('Error adding logo to SVG:', logoError);
    }
  }

  fs.writeFileSync(svgPath, svgContent);


  const pngOptions = {
    errorCorrectionLevel: errorCorrection,
    type: 'image/png',
    quality: 0.92,
    margin: margin,
    color: {
      dark: darkColor,
      light: lightColor
    },
    width: width
  };


  let pngBuffer = await QRCode.toBuffer(qrUrl, pngOptions);


  if (includeLogo && fs.existsSync(logoPath)) {
    try {
      console.log(`Attempting to add logo to PNG QR code: ${logoPath}`);


      const qrDataUrl = `data:image/png;base64,${pngBuffer.toString('base64')}`;

      console.log('PNG generated successfully. Logo functionality available in SVG version.');
    } catch (logoError) {
      console.error('Error processing PNG with logo:', logoError);
    }
  }


  const pngFilename = `qr.png`;
  const pngPath = path.join(qrCodeDir, pngFilename);
  fs.writeFileSync(pngPath, pngBuffer);

  const svgWebPath = `/qrcodes/${restaurantSlug}/${svgFilename}`;
  const pngWebPath = `/qrcodes/${restaurantSlug}/${pngFilename}`;

  console.log(`QR codes generated successfully:`);
  console.log(`- SVG: ${svgWebPath}`);
  console.log(`- PNG: ${pngWebPath}`);

  return {
    targetUrl: qrUrl,
    svgPath: svgWebPath,
    pngPath: pngWebPath,
    svgFilePath: svgPath,
    pngFilePath: pngPath,

    url: pngWebPath,
    path: pngPath,
    filename: pngFilename
  };
}
async function regenerateQRCode(restaurantSlug, options = {}) {
  try {
    console.log(`Regenerating QR codes for restaurant: ${restaurantSlug}`);


    const qrCodeDir = path.join(__dirname, '..', 'public', 'qrcodes', restaurantSlug);
    if (fs.existsSync(qrCodeDir)) {
      const files = fs.readdirSync(qrCodeDir);
      files.forEach(file => {
        if (file.startsWith('qr.') || file.startsWith('qr-')) {
          fs.unlinkSync(path.join(qrCodeDir, file));
        }
      });
    }


    return await generateQRCode(restaurantSlug, null, options);
  } catch (error) {
    console.error('Error regenerating QR codes:', error);
    throw error;
  }
}
app.get('/api/admin/export/csv/:restaurantId?', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const user = req.user;
    let restaurantId;


    if (user.role === 'super_admin' && req.params.restaurantId) {
      restaurantId = parseInt(req.params.restaurantId);
    }

    else if (user.role === 'restaurant_admin') {
      restaurantId = user.restaurant_id;
    }

    else {
      return res.status(400).json({
        success: false,
        message: 'Restaurant ID is required for super admin'
      });
    }
    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }
    const categoryTypes = await db.getCategoryTypesByRestaurant(restaurantId);
    const categories = await db.getCategoriesByRestaurant(restaurantId);
    const menuItems = await db.getMenuItemsByRestaurant(restaurantId);
    const workbook = XLSX.utils.book_new();


    const typesData = [
      ['Type name (mk)', 'Type name (en)'] // Headers
    ];
    categoryTypes.forEach(ct => {
      typesData.push([
        ct.name_mk || ct.name || '',
        ct.name_en || ''
      ]);
    });
    const typesSheet = XLSX.utils.aoa_to_sheet(typesData);
    XLSX.utils.book_append_sheet(workbook, typesSheet, 'Types');


    const categoriesData = [
      ['Category (mk)', 'Category (en)', 'Type'] // Headers
    ];
    categories.forEach(cat => {
      categoriesData.push([
        cat.name_mk || cat.name || '',
        cat.name_en || '',
        cat.type || ''
      ]);
    });
    const categoriesSheet = XLSX.utils.aoa_to_sheet(categoriesData);
    XLSX.utils.book_append_sheet(workbook, categoriesSheet, 'Categories');


    const menuItemsData = [
      ['Category', 'Name (mk)', 'Name (en)', 'Description (mk)', 'Description (en)', 'Price', 'Size Info', 'Allergens (mk)', 'Allergens (en)'] // Headers
    ];


    const menuItemsByCategory = {};
    menuItems.forEach(item => {
      if (!menuItemsByCategory[item.category_id]) {
        menuItemsByCategory[item.category_id] = [];
      }
      menuItemsByCategory[item.category_id].push(item);
    });


    categories.forEach(cat => {
      const itemsForCategory = menuItemsByCategory[cat.id] || [];
      itemsForCategory.forEach(item => {
        menuItemsData.push([
          cat.name_mk || cat.name || '',
          item.name_mk || item.name || '',
          item.name_en || '',
          item.description_mk || item.description || '',
          item.description_en || '',
          parseFloat(item.price || 0).toFixed(2),
          item.size_info || '',
          item.allergens_mk || item.allergens || '',
          item.allergens_en || ''
        ]);
      });
    });

    const menuItemsSheet = XLSX.utils.aoa_to_sheet(menuItemsData);
    XLSX.utils.book_append_sheet(workbook, menuItemsSheet, 'Menu Items');


    const xlsxBuffer = XLSX.write(workbook, {
      type: 'buffer',
      bookType: 'xlsx',
      compression: true
    });
    const filename = `${restaurant.slug}.xlsx`;

    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
    res.setHeader('Content-Length', xlsxBuffer.length);


    res.send(xlsxBuffer);

  } catch (error) {
    console.error('Error exporting XLSX:', error);
    res.status(500).json({ success: false, message: 'Failed to export XLSX: ' + error.message });
  }
});
app.get('/api/admin/restaurants-for-export', authMiddleware, adminMiddleware, async (req, res) => {
  try {
    const restaurants = await db.getAllRestaurants();
    const restaurantList = restaurants.map(r => ({
      id: r.id,
      name: r.name,
      slug: r.slug
    }));

    res.json({ success: true, restaurants: restaurantList });
  } catch (error) {
    console.error('Error getting restaurants for export:', error);
    res.status(500).json({ success: false, message: 'Failed to get restaurants' });
  }
});
app.get('/api/admin/download-excel-template', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {

    const workbook = XLSX.utils.book_new();


    const typesData = [
      ['Type name (mk)', 'Type name (en)'], // Headers
      ['Предјадења', 'Appetizers'],
      ['Супи', 'Soups'],
      ['Главни јадења', 'Main Courses'],
      ['Десерти', 'Desserts'],
      ['Пијалаци', 'Beverages'],
      ['Салати', 'Salads']
    ];
    const typesSheet = XLSX.utils.aoa_to_sheet(typesData);
    XLSX.utils.book_append_sheet(workbook, typesSheet, 'Types');


    const categoriesData = [
      ['Category (mk)', 'Category (en)', 'Type'], // Headers
      ['Ладни предјадења', 'Cold Appetizers', 'Предјадења'],
      ['Топли предјадења', 'Hot Appetizers', 'Предјадења'],
      ['Пилешка супа', 'Chicken Soup', 'Супи'],
      ['Зеленчукова супа', 'Vegetable Soup', 'Супи'],
      ['Скара', 'Grilled Dishes', 'Главни јадења'],
      ['Тестенини', 'Pasta Dishes', 'Главни јадења'],
      ['Сладолед', 'Ice Cream', 'Десерти'],
      ['Торти', 'Cakes', 'Десерти'],
      ['Топли напитоци', 'Hot Drinks', 'Пијалаци'],
      ['Ладни напитоци', 'Cold Drinks', 'Пијалаци'],
      ['Зелени салати', 'Green Salads', 'Салати']
    ];
    const categoriesSheet = XLSX.utils.aoa_to_sheet(categoriesData);
    XLSX.utils.book_append_sheet(workbook, categoriesSheet, 'Categories');


    const menuItemsData = [
      ['Category', 'Name (mk)', 'Name (en)', 'Description (mk)', 'Description (en)', 'Price', 'Size Info', 'Allergens (mk)', 'Allergens (en)'], // Headers
      ['Ладни предјадења', 'Цезар салата', 'Caesar Salad', 'Свежа ромејн салата со пармезан и крутони', 'Fresh romaine lettuce with parmesan and croutons', '12.50', 'Regular', 'Глутен, Млечни производи', 'Gluten, Dairy'],
      ['Ладни предјадења', 'Брускета', 'Bruschetta', 'Печен леб со домати и босилек', 'Toasted bread with tomatoes and basil', '8.00', 'Small', 'Глутен', 'Gluten'],
      ['Топли предјадења', 'Моцарела стапчиња', 'Mozzarella Sticks', 'Крцкава пржена моцарела со маринара сос', 'Crispy fried mozzarella with marinara sauce', '10.00', 'Regular', 'Млечни производи, Глутен', 'Dairy, Gluten'],
      ['Пилешка супа', 'Пилешка супа со резанци', 'Chicken Noodle Soup', 'Домашна пилешка супа со резанци', 'Homemade chicken soup with noodles', '7.50', 'Bowl', 'Глутен', 'Gluten'],
      ['Скара', 'Ролна на жар', 'Grilled Salmon', 'Свежа атлантска ролна со билки', 'Fresh Atlantic salmon with herbs', '24.00', 'Large', 'Риба', 'Fish'],
      ['Тестенини', 'Шпагети Карбонара', 'Spaghetti Carbonara', 'Класични тестенини со јајца, сирење и панчета', 'Classic pasta with eggs, cheese, and pancetta', '16.00', 'Regular', 'Глутен, Млечни производи, Јајца', 'Gluten, Dairy, Eggs'],
      ['Сладолед', 'Ванила сладолед', 'Vanilla Ice Cream', 'Премиум ванила сладолед', 'Premium vanilla ice cream', '5.00', 'Scoop', 'Млечни производи', 'Dairy'],
      ['Топли напитоци', 'Еспресо', 'Espresso', 'Италијанско еспресо кафе', 'Italian espresso coffee', '3.50', 'Cup', '', ''],
      ['Ладни напитоци', 'Свежо портокалово сок', 'Fresh Orange Juice', 'Свежо исцедено портокалово сок', 'Freshly squeezed orange juice', '4.00', 'Glass', '', ''],
      ['Зелени салати', 'Грчка салата', 'Greek Salad', 'Традиционална грчка салата со фета сирење', 'Traditional Greek salad with feta cheese', '13.00', 'Regular', 'Млечни производи', 'Dairy']
    ];
    const menuItemsSheet = XLSX.utils.aoa_to_sheet(menuItemsData);
    XLSX.utils.book_append_sheet(workbook, menuItemsSheet, 'Menu Items');


    const excelBuffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });


    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', 'attachment; filename="restaurant_data_template.xlsx"');


    res.send(excelBuffer);

  } catch (error) {
    console.error('Error generating Excel template:', error);
    res.status(500).json({ success: false, message: 'Failed to generate Excel template: ' + error.message });
  }
});
app.get('/api/admin/qrcode/:restaurantId?', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const user = req.user;
    let restaurantId;

    if (user.role === 'super_admin' && req.params.restaurantId) {
      restaurantId = parseInt(req.params.restaurantId);
    } else if (user.role === 'restaurant_admin') {
      restaurantId = user.restaurant_id;
    } else {
      return res.status(400).json({
        success: false,
        message: 'Restaurant ID is required'
      });
    }

    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }
    let qrCodeUrl = restaurant.qr_code_url;
    let needsGeneration = !qrCodeUrl;


    if (qrCodeUrl && !needsGeneration) {
      const qrFilePath = path.join(__dirname, '..', 'public', qrCodeUrl);
      if (!fs.existsSync(qrFilePath)) {
        needsGeneration = true;
        console.log(`QR code file not found at ${qrFilePath}, regenerating...`);
      }
    }

    if (needsGeneration) {

      try {
        const logoPath = restaurant.logo_url ?
          path.join(__dirname, '..', 'public', restaurant.logo_url) : null;

        const qrResult = await generateQRCode(restaurant.slug, logoPath);
        qrCodeUrl = qrResult.url;


        await db.updateRestaurant(restaurantId, {
          ...restaurant,
          qr_code_url: qrCodeUrl, // Legacy field
          qr_svg_path: qrResult.svgPath,
          qr_png_path: qrResult.pngPath,
          qr_target_url: qrResult.targetUrl
        });


        restaurant.qr_code_url = qrCodeUrl;
        restaurant.qr_svg_path = qrResult.svgPath;
        restaurant.qr_png_path = qrResult.pngPath;
        restaurant.qr_target_url = qrResult.targetUrl;

      } catch (error) {
        console.error('Error generating QR code:', error);
        return res.status(500).json({ success: false, message: 'Failed to generate QR code' });
      }
    }

    res.json({
      success: true,
      data: {
        restaurant_id: restaurantId,
        restaurant_name: restaurant.name,
        restaurant_slug: restaurant.slug,
        qr_code_url: qrCodeUrl, // Legacy field
        qr_svg_path: restaurant.qr_svg_path,
        qr_png_path: restaurant.qr_png_path,
        qr_target_url: restaurant.qr_target_url,
        logo_url: restaurant.logo_url
      }
    });
  } catch (error) {
    console.error('Error getting QR code:', error);
    res.status(500).json({ success: false, message: 'Failed to get QR code' });
  }
});
app.post('/api/admin/qrcode/regenerate-for-slug/:restaurantId/:newSlug', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const user = req.user;
    const restaurantId = parseInt(req.params.restaurantId);
    const newSlug = req.params.newSlug;


    if (user.role !== 'super_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }
    const options = req.body.options || {};
    const qrResult = await regenerateQRCode(newSlug, options);


    await db.updateRestaurant(restaurantId, {
      ...restaurant,
      slug: newSlug,
      qr_code_url: qrResult.url, // Legacy field
      qr_svg_path: qrResult.svgPath,
      qr_png_path: qrResult.pngPath,
      qr_target_url: qrResult.targetUrl
    });

    res.json({
      success: true,
      data: {
        restaurant_id: restaurantId,
        new_slug: newSlug,
        qr_code_url: qrResult.url,
        qr_svg_path: qrResult.svgPath,
        qr_png_path: qrResult.pngPath,
        qr_target_url: qrResult.targetUrl,
        message: 'QR codes regenerated for new slug successfully'
      }
    });
  } catch (error) {
    console.error('Error regenerating QR codes for new slug:', error);
    res.status(500).json({ success: false, message: 'Failed to regenerate QR codes for new slug' });
  }
});
app.post('/api/admin/qrcode/regenerate/:restaurantId?', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const user = req.user;
    let restaurantId;

    if (user.role === 'super_admin' && req.params.restaurantId) {
      restaurantId = parseInt(req.params.restaurantId);
    } else if (user.role === 'restaurant_admin') {
      restaurantId = user.restaurant_id;
    } else {
      return res.status(400).json({
        success: false,
        message: 'Restaurant ID is required'
      });
    }

    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }
    const options = req.body.options || {};

    const logoPath = restaurant.logo_url ?
      path.join(__dirname, '..', 'public', restaurant.logo_url) : null;

    const qrResult = await generateQRCode(restaurant.slug, logoPath, options);


    await db.updateRestaurant(restaurantId, {
      ...restaurant,
      qr_code_url: qrResult.url, // Legacy field
      qr_svg_path: qrResult.svgPath,
      qr_png_path: qrResult.pngPath,
      qr_target_url: qrResult.targetUrl
    });

    res.json({
      success: true,
      data: {
        qr_code_url: qrResult.url, // Legacy field
        qr_svg_path: qrResult.svgPath,
        qr_png_path: qrResult.pngPath,
        qr_target_url: qrResult.targetUrl,
        message: 'QR code regenerated successfully'
      }
    });
  } catch (error) {
    console.error('Error regenerating QR code:', error);
    res.status(500).json({ success: false, message: 'Failed to regenerate QR code' });
  }
});
app.get('/api/admin/qrcode/download/:restaurantId?', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const user = req.user;
    let restaurantId;

    if (user.role === 'super_admin' && req.params.restaurantId) {
      restaurantId = parseInt(req.params.restaurantId);
    } else if (user.role === 'restaurant_admin') {
      restaurantId = user.restaurant_id;
    } else {
      return res.status(400).json({
        success: false,
        message: 'Restaurant ID is required'
      });
    }

    const restaurant = await db.getRestaurantById(restaurantId);
    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }
    const format = req.query.format || 'png';
    let qrFilePath, filename, contentType;

    if (format.toLowerCase() === 'svg') {

      if (!restaurant.qr_svg_path) {
        return res.status(404).json({ success: false, message: 'SVG QR code not found' });
      }
      qrFilePath = path.join(__dirname, '..', 'public', restaurant.qr_svg_path);
      filename = `${restaurant.slug}-qrcode.svg`;
      contentType = 'image/svg+xml';
    } else {

      if (!restaurant.qr_png_path && !restaurant.qr_code_url) {
        return res.status(404).json({ success: false, message: 'PNG QR code not found' });
      }
      qrFilePath = path.join(__dirname, '..', 'public', restaurant.qr_png_path || restaurant.qr_code_url);
      filename = `${restaurant.slug}-qrcode.png`;
      contentType = 'image/png';
    }


    if (!fs.existsSync(qrFilePath)) {
      console.log(`QR code file not found at ${qrFilePath}, attempting to regenerate...`);
      try {
        const logoPath = restaurant.logo_url ?
          path.join(__dirname, '..', 'public', restaurant.logo_url) : null;

        const qrResult = await generateQRCode(restaurant.slug, logoPath, {});


        await db.updateRestaurant(restaurantId, {
          ...restaurant,
          qr_code_url: qrResult.url,
          qr_svg_path: qrResult.svgPath,
          qr_png_path: qrResult.pngPath,
          qr_target_url: qrResult.targetUrl
        });


        if (format.toLowerCase() === 'svg') {
          qrFilePath = path.join(__dirname, '..', 'public', qrResult.svgPath);
        } else {
          qrFilePath = path.join(__dirname, '..', 'public', qrResult.pngPath);
        }
      } catch (regenerateError) {
        console.error('Error regenerating QR code for download:', regenerateError);
        return res.status(500).json({ success: false, message: 'Failed to generate QR code file' });
      }
    }


    if (!fs.existsSync(qrFilePath)) {
      return res.status(404).json({ success: false, message: 'QR code file not found after regeneration' });
    }

    console.log(`Downloading QR code: ${qrFilePath}`);

    res.setHeader('Content-Type', contentType);
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);

    const fileStream = fs.createReadStream(qrFilePath);
    fileStream.pipe(res);
  } catch (error) {
    console.error('Error downloading QR code:', error);
    res.status(500).json({ success: false, message: 'Failed to download QR code' });
  }
});
async function processExcelData(db, workbook, restaurantId) {
  let created = 0;
  let updated = 0;
  let errors = [];
  let skipped = 0;

  try {
    console.log(`Processing Excel data for restaurant ${restaurantId}`);

    // STEP 1: Get existing data for this restaurant (instead of deleting)
    console.log(`Loading existing menu data for restaurant ${restaurantId}...`);
    const existingTypes = await db.getCategoryTypesByRestaurant(restaurantId);
    const existingCategories = await db.getCategoriesByRestaurant(restaurantId);
    const existingMenuItems = await db.getMenuItemsByRestaurant(restaurantId);
    
    // Create maps for quick lookup
    const existingTypesMap = new Map(existingTypes.map(t => [t.name_mk, t]));
    const existingCategoriesMap = new Map(existingCategories.map(c => [c.name_mk, c]));
    const existingMenuItemsMap = new Map(existingMenuItems.map(m => [m.name_mk, m]));

    // STEP 2: Import Types (Sheet 1)
    const typesSheet = workbook.Sheets['Types'];
    const typesData = XLSX.utils.sheet_to_json(typesSheet, { header: 1 });

    const typeMap = new Map(); // Map type name (mk) to type ID
    for (let i = 1; i < typesData.length; i++) {
      const row = typesData[i];
      if (!row || row.length < 2 || !row[0]) continue;

      const typeNameMk = String(row[0]).trim();
      const typeNameEn = row[1] ? String(row[1]).trim() : '';
      if (!typeNameMk) continue;

      try {
        // Check if type already exists
        const existingType = existingTypesMap.get(typeNameMk);
        if (existingType) {
          // Update existing type
          await db.updateCategoryType(existingType.id, {
            name: typeNameMk,
            name_mk: typeNameMk,
            name_en: typeNameEn,
            is_active: true,
            display_order: i
          });
          typeMap.set(typeNameMk, existingType.id);
          updated++;
          console.log(`Updated type: ${typeNameMk} (EN: ${typeNameEn})`);
        } else {
          // Create new type
          const typeResult = await db.createCategoryType({
            name: typeNameMk,
            name_mk: typeNameMk,
            name_en: typeNameEn,
            restaurant_id: restaurantId,
            is_active: true,
            display_order: i
          });
          typeMap.set(typeNameMk, typeResult);
          created++;
          console.log(`Created type: ${typeNameMk} (EN: ${typeNameEn})`);
        }
      } catch (error) {
        console.error(`Error processing type ${typeNameMk}:`, error);
        errors.push(`Type "${typeNameMk}": ${error.message}`);
      }
    }
    
    // STEP 3: Import Categories (Sheet 2)
    const categoriesSheet = workbook.Sheets['Categories'];
    const categoriesData = XLSX.utils.sheet_to_json(categoriesSheet, { header: 1 });

    const categoryMap = new Map(); // Map category name (mk) to category ID
    for (let i = 1; i < categoriesData.length; i++) {
      const row = categoriesData[i];
      if (!row || row.length < 3 || !row[0] || !row[2]) continue;

      const categoryNameMk = String(row[0]).trim();
      const categoryNameEn = row[1] ? String(row[1]).trim() : '';
      const typeName = String(row[2]).trim();

      if (!categoryNameMk || !typeName) continue;

      try {
        // Check if type exists in our map
        const typeId = typeMap.get(typeName);
        if (!typeId) {
          errors.push(`Category "${categoryNameMk}": Type "${typeName}" not found in Sheet 1`);
          continue;
        }

        // Check if category already exists
        const existingCategory = existingCategoriesMap.get(categoryNameMk);
        if (existingCategory) {
          // Update existing category
          await db.updateCategory(existingCategory.id, {
            name: categoryNameMk,
            name_mk: categoryNameMk,
            name_en: categoryNameEn,
            type: typeName,
            is_active: true,
            is_visible: true,
            display_order: i
          });
          categoryMap.set(categoryNameMk, existingCategory.id);
          updated++;
          console.log(`Updated category: ${categoryNameMk} (EN: ${categoryNameEn}, Type: ${typeName})`);
        } else {
          // Create new category
          const categoryResult = await db.createCategory({
            name: categoryNameMk,
            name_mk: categoryNameMk,
            name_en: categoryNameEn,
            type: typeName,
            restaurant_id: restaurantId,
            is_active: true,
            is_visible: true,
            display_order: i
          });
          categoryMap.set(categoryNameMk, categoryResult);
          created++;
          console.log(`Created category: ${categoryNameMk} (EN: ${categoryNameEn}, Type: ${typeName})`);
        }
      } catch (error) {
        console.error(`Error processing category ${categoryNameMk}:`, error);
        errors.push(`Category "${categoryNameMk}": ${error.message}`);
      }
    }
    
    // STEP 4: Import Menu Items (Sheet 3)
    const menuItemsSheet = workbook.Sheets['Menu Items'];
    const menuItemsData = XLSX.utils.sheet_to_json(menuItemsSheet, { header: 1 });

    for (let i = 1; i < menuItemsData.length; i++) {
      const row = menuItemsData[i];
      if (!row || row.length < 6 || !row[0] || !row[1]) continue;

      const categoryName = String(row[0]).trim();
      const itemNameMk = String(row[1]).trim();
      const itemNameEn = row[2] ? String(row[2]).trim() : '';
      const descriptionMk = row[3] ? String(row[3]).trim() : '';
      const descriptionEn = row[4] ? String(row[4]).trim() : '';
      const price = row[5] ? parseFloat(row[5]) : 0;
      const sizeInfo = row[6] ? String(row[6]).trim() : '';
      const allergensMk = row[7] ? String(row[7]).trim() : '';
      const allergensEn = row[8] ? String(row[8]).trim() : '';

      if (!categoryName || !itemNameMk) continue;

      try {
        // Check if category exists in our map
        const categoryId = categoryMap.get(categoryName);
        if (!categoryId) {
          errors.push(`Menu item "${itemNameMk}": Category "${categoryName}" not found in Sheet 2`);
          continue;
        }

        const menuItemData = {
          name: itemNameMk,
          name_mk: itemNameMk,
          name_en: itemNameEn,
          description: descriptionMk,
          description_mk: descriptionMk,
          description_en: descriptionEn,
          price: price,
          size_info: sizeInfo,
          allergens: allergensMk,
          allergens_mk: allergensMk,
          allergens_en: allergensEn,
          category_id: categoryId,
          display_order: i
        };

        // Check if menu item already exists
        const existingItem = existingMenuItemsMap.get(itemNameMk);
        if (existingItem) {
          // Update existing menu item
          await db.updateMenuItem(existingItem.id, menuItemData);
          updated++;
          console.log(`Updated menu item: ${itemNameMk} (EN: ${itemNameEn}, Category: ${categoryName})`);
        } else {
          // Create new menu item
          const menuItemResult = await db.createMenuItem({
            ...menuItemData,
            restaurant_id: restaurantId,
            is_active: true,
            is_visible: true,
            is_on_sale: false,
            sale_type: null,
            sale_value: null,
            original_price: null
          });
          created++;
          console.log(`Created menu item: ${itemNameMk} (EN: ${itemNameEn}, Category: ${categoryName})`);
        }
      } catch (error) {
        console.error(`Error processing menu item ${itemNameMk}:`, error);
        errors.push(`Menu item "${itemNameMk}": ${error.message}`);
      }
    }

  } catch (error) {
    console.error('Error in processExcelData:', error);
    errors.push(`Processing error: ${error.message}`);
  }

  console.log(`Excel Processing completed: ${created} created, ${updated} updated, ${skipped} skipped, ${errors.length} errors`);
  return { created, updated, errors, skipped };
}
async function uploadSimplifiedCSV(db, rows, restaurantId, overrideMenu = true) {
  let created = 0;
  let errors = [];
  let skipped = 0;
  let typeOrder = 1;
  let categoryOrder = 1;
  let itemOrder = 1;
  if (overrideMenu) {
    console.log(`Clearing existing menu data for restaurant ${restaurantId}...`);

    try {

      await db.deleteAllMenuItemsByRestaurant(restaurantId);
      await db.deleteAllCategoriesByRestaurant(restaurantId);
      await db.deleteAllCategoryTypesByRestaurant(restaurantId);

      console.log('Existing menu data cleared successfully');
    } catch (error) {
      console.error('Error clearing existing menu data:', error);
      throw new Error('Failed to clear existing menu data: ' + error.message);
    }
  }
  let existingTypes = await db.getCategoryTypesByRestaurant(restaurantId);
  let existingCategories = await db.getCategoriesByRestaurant(restaurantId);
  let existingMenuItems = await db.getMenuItemsByRestaurant(restaurantId);
  const typeCategoryMap = new Map();
  let currentType = null;
  let currentCategory = null;

  console.log(`Processing ${rows.length} CSV rows for restaurant ${restaurantId}`);

  for (let i = 0; i < rows.length; i++) {
    const row = rows[i];

    try {

      if (i === 0 || (!row.type && !row.category && !row.name)) {
        continue;
      }
      const type = row.type ? row.type.trim() : null;
      const category = row.category ? row.category.trim() : null;
      const name = row.name ? row.name.trim() : null;
      const description = row.description ? row.description.trim() : null;
      const price = row.price ? parseFloat(row.price) : null;
      const sizeInfo = row.size_info ? row.size_info.trim() : null;
      const allergens = row.allergens ? row.allergens.trim() : null;
      if (type && !category && !name) {

        currentType = type;
        currentCategory = null; // Reset current category when type changes

        let typeExists = existingTypes.some(ct => ct.name === type);
        if (!typeExists) {
          await db.createCategoryType({
            restaurant_id: restaurantId,
            name: type,
            name_mk: type,
            name_en: type,
            display_order: typeOrder++
          });
          existingTypes.push({ name: type, id: Date.now() }); // Add to cache
          created++;
          console.log(`Created new type: ${type}`);
        }
      }
      else if (!type && category && !name) {

        if (!currentType) {
          errors.push(`Row ${i + 1}: Category "${category}" found but no current type set. Ensure type is defined before categories.`);
          continue;
        }

        let categoryExists = existingCategories.some(c => c.name === category && c.type === currentType);
        if (!categoryExists) {
          const newCategoryResult = await db.createCategory({
            restaurant_id: restaurantId,
            name: category,
            name_mk: category,
            name_en: category,
            type: currentType,
            description: null,
            display_order: categoryOrder++,
            is_visible: true
          });
          const newCategory = { name: category, type: currentType, id: newCategoryResult.insertId || Date.now() };
          existingCategories.push(newCategory);
          currentCategory = newCategory;
          created++;
          console.log(`Created new category: ${category} under type ${currentType}`);
        } else {
          currentCategory = existingCategories.find(c => c.name === category && c.type === currentType);
        }
      }
      else if (!type && !category && name) {

        if (!currentCategory) {
          errors.push(`Row ${i + 1}: Menu item "${name}" found but no current category set. Ensure category is defined before menu items.`);
          continue;
        }

        if (!price || isNaN(price)) {
          errors.push(`Row ${i + 1}: Valid price is required for menu item "${name}"`);
          continue;
        }
        const existingItem = existingMenuItems.find(item =>
          item.name === name &&
          item.category_id === currentCategory.id
        );

        if (existingItem) {

          const isDifferent = (
            (description !== (existingItem.description || null)) ||
            (sizeInfo !== (existingItem.size_info || null)) ||
            (price !== existingItem.price) ||
            (allergens !== (existingItem.allergens || null))
          );

          if (isDifferent) {

            await db.createMenuItem({
              restaurant_id: restaurantId,
              category_id: currentCategory.id,
              name: name,
              description: description,
              price: price,
              size_info: sizeInfo,
              allergens: allergens,
              display_order: itemOrder++
            });
            existingMenuItems.push({ name: name, category_id: currentCategory.id, description, size_info: sizeInfo, price, allergens });
            created++;
            console.log(`Created menu item variant: ${name} (different details)`);
          } else {

            skipped++;
            console.log(`Skipped duplicate menu item: ${name} (identical details)`);
          }
        } else {

          await db.createMenuItem({
            restaurant_id: restaurantId,
            category_id: currentCategory.id,
            name: name,
            description: description,
            price: price,
            size_info: sizeInfo,
            allergens: allergens,
            display_order: itemOrder++
          });
          existingMenuItems.push({ name: name, category_id: currentCategory.id, description, size_info: sizeInfo, price, allergens });
          created++;
          console.log(`Created new menu item: ${name}`);
        }
      }
      else if (type && category && name) {

        currentType = type;


        let typeExists = existingTypes.some(ct => ct.name === type);
        if (!typeExists) {
          await db.createCategoryType({
            restaurant_id: restaurantId,
            name: type,
            name_mk: type,
            name_en: type,
            display_order: typeOrder++
          });
          existingTypes.push({ name: type, id: Date.now() }); // Add to cache
          created++;
          console.log(`Created new type: ${type}`);
        }
        let categoryExists = existingCategories.some(c => c.name === category && c.type === type);
        if (!categoryExists) {
          const newCategoryResult = await db.createCategory({
            restaurant_id: restaurantId,
            name: category,
            name_mk: category,
            name_en: category,
            type: type,
            description: null,
            display_order: categoryOrder++,
            is_visible: true
          });
          const newCategory = { name: category, type: type, id: newCategoryResult.insertId || Date.now() };
          existingCategories.push(newCategory);
          currentCategory = newCategory;
          created++;
          console.log(`Created new category: ${category} under type ${type}`);
        } else {
          currentCategory = existingCategories.find(c => c.name === category && c.type === type);
        }
        if (!price || isNaN(price)) {
          errors.push(`Row ${i + 1}: Valid price is required for menu item "${name}"`);
          continue;
        }
        const existingItem = existingMenuItems.find(item =>
          item.name === name &&
          item.category_id === currentCategory.id
        );

        if (existingItem) {

          const isDifferent = (
            (description !== (existingItem.description || null)) ||
            (sizeInfo !== (existingItem.size_info || null)) ||
            (price !== existingItem.price) ||
            (allergens !== (existingItem.allergens || null))
          );

          if (isDifferent) {

            await db.createMenuItem({
              restaurant_id: restaurantId,
              category_id: currentCategory.id,
              name: name,
              description: description,
              price: price,
              size_info: sizeInfo,
              allergens: allergens,
              display_order: itemOrder++
            });
            existingMenuItems.push({ name: name, category_id: currentCategory.id, description, size_info: sizeInfo, price, allergens });
            created++;
            console.log(`Created menu item variant: ${name} (different details)`);
          } else {

            skipped++;
            console.log(`Skipped duplicate menu item: ${name} (identical details)`);
          }
        } else {

          await db.createMenuItem({
            restaurant_id: restaurantId,
            category_id: currentCategory.id,
            name: name,
            description: description,
            price: price,
            size_info: sizeInfo,
            allergens: allergens,
            display_order: itemOrder++
          });
          existingMenuItems.push({ name: name, category_id: currentCategory.id, description, size_info: sizeInfo, price, allergens });
          created++;
          console.log(`Created new menu item: ${name}`);
        }
      }
      else {

        console.log(`Row ${i + 1}: Skipped - invalid pattern or empty row`);
      }
    } catch (error) {
      errors.push(`Row ${i + 1}: ${error.message}`);
      console.error(`Error processing row ${i + 1}:`, error);
    }
  }

  console.log(`CSV Processing completed: ${created} created, ${skipped} skipped, ${errors.length} errors`);
  return { created, errors, skipped };
}
// Theme API endpoints
app.get('/api/themes', async (req, res) => {
  try {
    const themes = await db.getAllThemes();
    res.json({ success: true, data: themes });
  } catch (error) {
    console.error('Error fetching themes:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch themes' });
  }
});

app.get('/api/themes/:id', async (req, res) => {
  try {
    const themeId = parseInt(req.params.id);
    const theme = await db.getThemeById(themeId);

    if (!theme) {
      return res.status(404).json({ success: false, message: 'Theme not found' });
    }

    res.json({ success: true, data: theme });
  } catch (error) {
    console.error('Error fetching theme:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch theme' });
  }
});

app.get('/api/restaurants/slug/:slug/theme', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    let theme;
    if (restaurant.selected_theme) {
      theme = await db.getThemeById(restaurant.selected_theme);
    }

    // If no theme selected or theme not found, use default
    if (!theme) {
      theme = await db.getDefaultTheme();
    }

    res.json({ success: true, data: theme });
  } catch (error) {
    console.error('Error fetching restaurant theme:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch restaurant theme' });
  }
});

// Hot Items API endpoints
app.put('/api/admin/menu-items/:id/toggle-hot', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const menuItemId = parseInt(req.params.id);
    const user = req.user;

    // Get menu item to verify restaurant ownership
    const [menuItemRows] = await db.pool.execute(
      'SELECT restaurant_id FROM menu_items WHERE id = ?',
      [menuItemId]
    );

    if (menuItemRows.length === 0) {
      return res.status(404).json({ success: false, message: 'Menu item not found' });
    }

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== menuItemRows[0].restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const isHotItem = await db.toggleHotItem(menuItemId);
    res.json({ success: true, is_hot_item: isHotItem });
  } catch (error) {
    console.error('Error toggling hot item:', error);
    res.status(500).json({ success: false, message: 'Failed to toggle hot item' });
  }
});

app.get('/api/restaurants/:id/hot-items', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const hotItems = await db.getHotItemsByRestaurant(restaurantId);
    res.json({ success: true, data: hotItems });
  } catch (error) {
    console.error('Error fetching hot items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch hot items' });
  }
});

app.get('/api/restaurants/slug/:slug/hot-items', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const hotItems = await db.getHotItemsByRestaurantFromTable(restaurant.id);
    res.json({ success: true, data: hotItems });
  } catch (error) {
    console.error('Error fetching hot items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch hot items' });
  }
});

// Admin Hot Items CRUD endpoints
app.get('/api/admin/restaurants/:id/hot-items', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const hotItems = await db.getAllHotItemsByRestaurant(restaurantId);
    res.json({ success: true, data: hotItems });
  } catch (error) {
    console.error('Error fetching hot items:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch hot items' });
  }
});

app.get('/api/admin/hot-items/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const hotItemId = parseInt(req.params.id);
    const hotItem = await db.getHotItemById(hotItemId);

    if (!hotItem) {
      return res.status(404).json({ success: false, message: 'Hot item not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== hotItem.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    res.json({ success: true, data: hotItem });
  } catch (error) {
    console.error('Error fetching hot item:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch hot item' });
  }
});

app.post('/api/admin/hot-items', authMiddleware, restaurantAdminMiddleware, imageUpload.single('image'), async (req, res) => {
  try {
    const {
      restaurant_id, name, name_mk, name_en, name_al,
      description, description_mk, description_en, description_al,
      price, size_info, allergens, allergens_mk, allergens_en, allergens_al,
      is_active, is_visible, display_order
    } = req.body;

    const user = req.user;

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== parseInt(restaurant_id)) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    let imageUrl = null;
    if (req.file) {
      // Get restaurant info to create proper path
      const restaurant = await db.getRestaurantById(restaurant_id);
      if (restaurant) {
        const itemName = (name_mk || name || 'hot-item').replace(/[^a-z0-9]/gi, '-').toLowerCase();
        const ext = path.extname(req.file.originalname);
        const uploadsDir = path.join(__dirname, '..', 'public', 'uploads', 'hot-items', restaurant.slug);

        // Create directory if it doesn't exist
        if (!fs.existsSync(uploadsDir)) {
          fs.mkdirSync(uploadsDir, { recursive: true });
        }

        const newFilename = `${itemName}${ext}`;
        const newPath = path.join(uploadsDir, newFilename);

        // Move file from tmp to proper location
        fs.renameSync(req.file.path, newPath);

        imageUrl = `/uploads/hot-items/${restaurant.slug}/${newFilename}`;
      } else {
        imageUrl = `/uploads/${req.file.filename}`;
      }
    }

    const hotItemId = await db.createHotItem(
      restaurant_id, name, name_mk, name_en, name_al,
      description, description_mk, description_en, description_al,
      price, size_info, allergens, allergens_mk, allergens_en, allergens_al,
      imageUrl, is_active !== 'false', is_visible !== 'false', display_order || 0
    );

    res.json({ success: true, id: hotItemId });
  } catch (error) {
    console.error('Error creating hot item:', error);
    res.status(500).json({ success: false, message: 'Failed to create hot item' });
  }
});

app.put('/api/admin/hot-items/:id', authMiddleware, restaurantAdminMiddleware, imageUpload.single('image'), async (req, res) => {
  try {
    const hotItemId = parseInt(req.params.id);
    const hotItem = await db.getHotItemById(hotItemId);

    if (!hotItem) {
      return res.status(404).json({ success: false, message: 'Hot item not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== hotItem.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const updateData = { ...req.body };

    // Handle photo deletion
    if (updateData.delete_photo === 'true' && hotItem.image_url) {
      try {
        const imagePath = path.join(__dirname, '..', 'public', hotItem.image_url);
        if (fs.existsSync(imagePath)) {
          fs.unlinkSync(imagePath);
        }
      } catch (err) {
        console.error('Error deleting image file:', err);
      }
      updateData.image_url = null;
    }

    if (req.file) {
      // Delete old image if exists
      if (hotItem.image_url) {
        try {
          const oldImagePath = path.join(__dirname, '..', 'public', hotItem.image_url);
          if (fs.existsSync(oldImagePath)) {
            fs.unlinkSync(oldImagePath);
          }
        } catch (err) {
          console.error('Error deleting old image:', err);
        }
      }

      // Get restaurant info to create proper path
      const restaurant = await db.getRestaurantById(hotItem.restaurant_id);
      if (restaurant) {
        const itemName = (updateData.name_mk || updateData.name || hotItem.name_mk || hotItem.name || 'hot-item').replace(/[^a-z0-9]/gi, '-').toLowerCase();
        const ext = path.extname(req.file.originalname);
        const uploadsDir = path.join(__dirname, '..', 'public', 'uploads', 'hot-items', restaurant.slug);

        // Create directory if it doesn't exist
        if (!fs.existsSync(uploadsDir)) {
          fs.mkdirSync(uploadsDir, { recursive: true });
        }

        const newFilename = `${itemName}${ext}`;
        const newPath = path.join(uploadsDir, newFilename);

        // Move file from tmp to proper location
        fs.renameSync(req.file.path, newPath);

        updateData.image_url = `/uploads/hot-items/${restaurant.slug}/${newFilename}`;
      } else {
        updateData.image_url = `/uploads/${req.file.filename}`;
      }
    }

    // Remove delete_photo flag before database update
    delete updateData.delete_photo;

    // Convert string booleans to actual booleans
    if (updateData.is_active !== undefined) {
      updateData.is_active = updateData.is_active !== 'false';
    }
    if (updateData.is_visible !== undefined) {
      updateData.is_visible = updateData.is_visible !== 'false';
    }

    await db.updateHotItem(hotItemId, updateData);
    res.json({ success: true });
  } catch (error) {
    console.error('Error updating hot item:', error);
    res.status(500).json({ success: false, message: 'Failed to update hot item' });
  }
});

app.delete('/api/admin/hot-items/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const hotItemId = parseInt(req.params.id);
    const hotItem = await db.getHotItemById(hotItemId);

    if (!hotItem) {
      return res.status(404).json({ success: false, message: 'Hot item not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== hotItem.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    await db.deleteHotItem(hotItemId);
    res.json({ success: true });
  } catch (error) {
    console.error('Error deleting hot item:', error);
    res.status(500).json({ success: false, message: 'Failed to delete hot item' });
  }
});

// Celebration Menu API endpoints
app.get('/api/admin/restaurants/:id/celebration-menus', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const user = req.user;

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const celebrationMenus = await db.getCelebrationMenusByRestaurant(restaurantId);

    // Get sections for each celebration menu
    for (let menu of celebrationMenus) {
      menu.sections = await db.getCelebrationMenuSections(menu.id);
    }

    res.json({ success: true, data: celebrationMenus });
  } catch (error) {
    console.error('Error fetching celebration menus:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch celebration menus' });
  }
});

app.get('/api/admin/celebration-menus/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const celebrationMenuId = parseInt(req.params.id);
    const celebrationMenu = await db.getCelebrationMenuById(celebrationMenuId);

    if (!celebrationMenu) {
      return res.status(404).json({ success: false, message: 'Celebration menu not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== celebrationMenu.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    celebrationMenu.sections = await db.getCelebrationMenuSections(celebrationMenuId);

    res.json({ success: true, data: celebrationMenu });
  } catch (error) {
    console.error('Error fetching celebration menu:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch celebration menu' });
  }
});

app.post('/api/admin/celebration-menus', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const { restaurant_id, name, name_mk, name_en, name_al, price_per_person, disclaimer, disclaimer_mk, disclaimer_en, disclaimer_al, is_active, is_visible, display_order, sections } = req.body;
    const user = req.user;

    // Verify access
    if (user.role === 'restaurant_admin' && user.restaurant_id !== restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const celebrationMenuId = await db.createCelebrationMenu(
      restaurant_id, name, name_mk, name_en, name_al, price_per_person, disclaimer, disclaimer_mk, disclaimer_en, disclaimer_al, is_active, is_visible, display_order || 0
    );

    // Create sections if provided
    if (sections && Array.isArray(sections)) {
      for (let i = 0; i < sections.length; i++) {
        const section = sections[i];
        await db.createCelebrationMenuSection(
          celebrationMenuId,
          section.title,
          section.title_mk,
          section.title_en,
          section.title_al,
          section.description,
          section.description_mk,
          section.description_en,
          section.description_al,
          i
        );
      }
    }

    res.json({ success: true, id: celebrationMenuId });
  } catch (error) {
    console.error('Error creating celebration menu:', error);
    res.status(500).json({ success: false, message: 'Failed to create celebration menu' });
  }
});

app.put('/api/admin/celebration-menus/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const celebrationMenuId = parseInt(req.params.id);
    const { name, name_mk, name_en, name_al, price_per_person, disclaimer, disclaimer_mk, disclaimer_en, disclaimer_al, is_active, is_visible, display_order, sections } = req.body;

    const celebrationMenu = await db.getCelebrationMenuById(celebrationMenuId);
    if (!celebrationMenu) {
      return res.status(404).json({ success: false, message: 'Celebration menu not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== celebrationMenu.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    await db.updateCelebrationMenu(
      celebrationMenuId,
      name ?? null,
      name_mk ?? null,
      name_en ?? null,
      name_al ?? null,
      price_per_person ?? null,
      disclaimer ?? null,
      disclaimer_mk ?? null,
      disclaimer_en ?? null,
      disclaimer_al ?? null,
      is_active ?? null,
      is_visible ?? null,
      display_order ?? 0
    );

    // Delete existing sections and recreate
    if (sections && Array.isArray(sections)) {
      await db.deleteCelebrationMenuSections(celebrationMenuId);
      for (let i = 0; i < sections.length; i++) {
        const section = sections[i];
        await db.createCelebrationMenuSection(
          celebrationMenuId,
          section.title ?? null,
          section.title_mk ?? null,
          section.title_en ?? null,
          section.title_al ?? null,
          section.description ?? null,
          section.description_mk ?? null,
          section.description_en ?? null,
          section.description_al ?? null,
          i
        );
      }
    }

    res.json({ success: true });
  } catch (error) {
    console.error('Error updating celebration menu:', error);
    res.status(500).json({ success: false, message: 'Failed to update celebration menu' });
  }
});

app.delete('/api/admin/celebration-menus/:id', authMiddleware, restaurantAdminMiddleware, async (req, res) => {
  try {
    const celebrationMenuId = parseInt(req.params.id);

    const celebrationMenu = await db.getCelebrationMenuById(celebrationMenuId);
    if (!celebrationMenu) {
      return res.status(404).json({ success: false, message: 'Celebration menu not found' });
    }

    const user = req.user;
    if (user.role === 'restaurant_admin' && user.restaurant_id !== celebrationMenu.restaurant_id) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    await db.deleteCelebrationMenu(celebrationMenuId);
    res.json({ success: true });
  } catch (error) {
    console.error('Error deleting celebration menu:', error);
    res.status(500).json({ success: false, message: 'Failed to delete celebration menu' });
  }
});

app.get('/api/restaurants/:id/celebration-menus', async (req, res) => {
  try {
    const restaurantId = parseInt(req.params.id);
    const restaurant = await db.getRestaurantById(restaurantId);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const celebrationMenus = await db.getVisibleCelebrationMenusByRestaurant(restaurantId);

    // Get sections for each celebration menu
    for (let menu of celebrationMenus) {
      menu.sections = await db.getCelebrationMenuSections(menu.id);
    }

    res.json({ success: true, data: celebrationMenus });
  } catch (error) {
    console.error('Error fetching celebration menus:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch celebration menus' });
  }
});

app.get('/api/restaurants/slug/:slug/celebration-menus', async (req, res) => {
  try {
    const restaurantSlug = req.params.slug;
    const restaurant = await db.getRestaurantBySlug(restaurantSlug);

    if (!restaurant) {
      return res.status(404).json({ success: false, message: 'Restaurant not found' });
    }

    if (!restaurant.is_active) {
      return res.status(403).json({ success: false, message: 'Restaurant is not available' });
    }

    const celebrationMenus = await db.getVisibleCelebrationMenusByRestaurant(restaurant.id);

    // Get sections for each celebration menu
    for (let menu of celebrationMenus) {
      menu.sections = await db.getCelebrationMenuSections(menu.id);
    }

    res.json({ success: true, data: celebrationMenus });
  } catch (error) {
    console.error('Error fetching celebration menus:', error);
    res.status(500).json({ success: false, message: 'Failed to fetch celebration menus' });
  }
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server running on port ${PORT}`);
});

export default app;