// backend/server.js
const express = require('express');
const mysql = require('mysql2');
const cors = require('cors');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

const app = express();
app.use(cors());
app.use(express.json());

// Hardcoded secret key instead of using process.env
const JWT_SECRET = 'rwanda_secret_key_2026';

// Database Connection Config
const db = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '', // Adjust to your local MySQL config
    database: 'RRBMS'
});

db.connect(err => {
    if (err) {
        console.error('Database connection failed: ' + err.stack);
        return;
    }
    console.log('Connected to RRBMS Database.');
});

// --- Authentication Middleware ---
const authenticateToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    if (!token) return res.sendStatus(401);

    jwt.verify(token, JWT_SECRET, (err, user) => {
        if (err) return res.sendStatus(403);
        req.user = user;
        next();
    });
};

// --- Auth Routes ---

// Registration Endpoint
app.post('/api/auth/register', async (req, res) => {
    const { username, password } = req.body;
    
    if (!username || !password) {
        return res.status(400).json({ error: 'Username and password are required' });
    }

    db.query('SELECT * FROM users WHERE username = ?', [username], async (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        if (results.length > 0) return res.status(400).json({ error: 'Username is already taken' });

        try {
            const salt = await bcrypt.genSalt(10);
            const hashedPassword = await bcrypt.hash(password, salt);

            db.query('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword], (err, result) => {
                if (err) return res.status(500).json({ error: err.message });
                res.status(201).json({ message: 'User registered successfully!', userId: result.insertId });
            });
        } catch (error) {
            res.status(500).json({ error: 'Internal server registration error' });
        }
    });
});

// Login Endpoint
app.post('/api/auth/login', (req, res) => {
    const { username, password } = req.body;
    db.query('SELECT * FROM users WHERE username = ?', [username], async (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        if (results.length === 0) return res.status(400).json({ error: 'User not found' });

        const user = results[0];
        const validPassword = await bcrypt.compare(password, user.password);
        if (!validPassword) return res.status(400).json({ error: 'Invalid password' });

        const token = jwt.sign({ id: user.id, username: user.username }, JWT_SECRET, { expiresIn: '8h' });
        res.json({ token });
    });
});

// --- Menu Management ---
app.get('/api/menu', (req, res) => {
    db.query('SELECT * FROM MenuServices', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/menu', authenticateToken, (req, res) => {
    const { ItemName, ItemPrice } = req.body;
    db.query('INSERT INTO MenuServices (ItemName, ItemPrice) VALUES (?, ?)', [ItemName, ItemPrice], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.status(201).json({ id: result.insertId, ItemName, ItemPrice });
    });
});

// --- Table Management ---
app.get('/api/tables', (req, res) => {
    db.query('SELECT * FROM CustomerTable', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

// Inside your backend server file
app.post('/api/tables', (req, res) => {
  let { TableNumber, CustomerName, GuestCount, Phone, WaiterName } = req.body;
  
  // Guard check: Truncate data string if it threatens your DB column width thresholds
  if (CustomerName && CustomerName.length > 255) {
    CustomerName = CustomerName.substring(0, 250) + "...*";
  }
  
  const query = `INSERT INTO CustomerTable (TableNumber, CustomerName, GuestCount, Phone, WaiterName) VALUES (?, ?, ?, ?, ?)`;
  
  db.query(query, [TableNumber, CustomerName, GuestCount, Phone, WaiterName], (err, result) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: err.message });
    }
    res.json({ message: "Table session registered successfully!" });
  });
});

// --- Reservations (Full CRUD Required) ---
app.get('/api/reservations', (req, res) => {
    const query = `
        SELECT r.*, c.CustomerName, c.Phone 
        FROM ReservationRecord r 
        JOIN CustomerTable c ON r.TableNumber = c.TableNumber`;
    db.query(query, (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/reservations', authenticateToken, (req, res) => {
    const { TableNumber, VisitDate } = req.body;
    db.query('INSERT INTO ReservationRecord (TableNumber, VisitDate) VALUES (?, ?)', [TableNumber, VisitDate], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.status(201).json({ ReservationID: result.insertId, TableNumber, VisitDate });
    });
});

app.put('/api/reservations/:id', authenticateToken, (req, res) => {
    const { TableNumber, VisitDate } = req.body;
    db.query('UPDATE ReservationRecord SET TableNumber = ?, VisitDate = ? WHERE ReservationID = ?', 
    [TableNumber, VisitDate, req.params.id], (err) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Reservation updated successfully' });
    });
});

// --- Payments & Revenue Handling ---
app.post('/api/payments', authenticateToken, (req, res) => {
    const { TableNumber, AmountPaid, PaymentDate } = req.body;
    db.query('INSERT INTO Payment (TableNumber, AmountPaid, PaymentDate) VALUES (?, ?, ?)', 
    [TableNumber, AmountPaid, PaymentDate], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.status(201).json({ PaymentID: result.insertId, TableNumber, AmountPaid, PaymentDate });
    });
});

// --- Reports API ---
app.get('/api/reports/daily', (req, res) => {
    const today = new Date().toISOString().split('T')[0];
    const query = `
        SELECT p.PaymentID, p.TableNumber, p.AmountPaid, c.WaiterName, c.CustomerName 
        FROM Payment p
        JOIN CustomerTable c ON p.TableNumber = c.TableNumber
        WHERE p.PaymentDate = ?`;
    
    db.query(query, [today], (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        
        const totalRevenue = results.reduce((sum, item) => sum + parseFloat(item.AmountPaid), 0);
        res.json({ tablesServed: results, totalRevenue });
    });
});

app.listen(5000, () => console.log('Server running on port 5000'));