const express = require('express');
const mysql = require('mysql2');
const cors = require('cors');
const session = require('express-session');
const bcrypt = require('bcrypt');
const dotenv = require('dotenv');

dotenv.config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors({
    origin: 'http://localhost:5173',
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
    credentials: true
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use(session({
    secret: process.env.SESSION_SECRET || 'taste_of_rwanda_secret_key_2026',
    resave: false,
    saveUninitialized: false,
    cookie: {
        secure: false,
        maxAge: 1000 * 60 * 60 * 24
    }
}));

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

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

// --- AUTH ROUTING ---
app.post('/api/register', (req, res) => {
    const { username, password } = req.body;
    if (!username || !password) return res.status(400).json({ message: 'Fields 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({ message: 'Username taken.' });

        try {
            const hashedPassword = await bcrypt.hash(password, 10);
            db.query('INSERT INTO Users (Username, Password) VALUES (?, ?)', [username, hashedPassword], (err) => {
                if (err) return res.status(500).json({ error: err.message });
                res.status(201).json({ message: 'User registered successfully.' });
            });
        } catch (error) {
            res.status(500).json({ message: 'Error hashing password.' });
        }
    });
});

app.post('/api/login', (req, finalRes) => {
    const { username, password } = req.body;
    db.query('SELECT * FROM Users WHERE Username = ?', [username], async (err, results) => {
        if (err) return finalRes.status(500).json({ error: err.message });
        if (results.length === 0) return finalRes.status(401).json({ message: 'Invalid credentials' });

        const user = results[0];
        const match = await bcrypt.compare(password, user.Password);
        if (!match) return finalRes.status(401).json({ message: 'Invalid credentials' });

        req.session.userId = user.UserID;
        req.session.username = user.Username;
        finalRes.json({ loggedIn: true, username: user.Username });
    });
});

app.post('/api/logout', (req, res) => {
    req.session.destroy(() => {
        res.clearCookie('connect.sid');
        res.json({ loggedIn: false });
    });
});

app.get('/api/session', (req, res) => {
    if (req.session.userId) res.json({ loggedIn: true, username: req.session.username });
    else res.json({ loggedIn: false });
});

// --- TABLES ---
app.post('/api/tables', (req, res) => {
    const { tableNumber, customerName, guestCount, phone, waiterName } = req.body;
    const query = 'INSERT INTO CustomerTable (TableNumber, CustomerName, GuestCount, Phone, WaiterName) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE CustomerName=?, GuestCount=?, Phone=?, WaiterName=?';
    db.query(query, [tableNumber, customerName, guestCount, phone, waiterName, customerName, guestCount, phone, waiterName], (err) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Table record saved' });
    });
});

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);
    });
});

// --- MENU SERVICES ---
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);
    });
});

// --- ORDER PLACEMENT BRIDGE ROUTE ---
app.post('/api/orders', (req, res) => {
    const { reservationId, menuId, quantity } = req.body;
    if (!reservationId || !menuId || !quantity) {
        return res.status(400).json({ message: 'Missing fields for item placement.' });
    }
    const query = 'INSERT INTO OrderItems (ReservationID, MenuID, Quantity) VALUES (?, ?, ?)';
    db.query(query, [reservationId, menuId, quantity], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Item added to order successfully', orderId: result.insertId });
    });
});

// --- RESERVATIONS ---
app.post('/api/reservations', (req, res) => {
    const { tableNumber, visitDate } = req.body;
    db.query('INSERT INTO ReservationRecord (TableNumber, VisitDate, Status) VALUES (?, ?, "Active")', [tableNumber, visitDate], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Reservation created successfully', reservationId: result.insertId });
    });
});

app.get('/api/reservations', (req, res) => {
    const query = `
        SELECT r.ReservationID, r.TableNumber, r.VisitDate, r.Status, c.CustomerName, c.WaiterName,
               GROUP_CONCAT(CONCAT(m.ItemName, ' (x', o.Quantity, ')') SEPARATOR ', ') AS OrderedItems,
               COALESCE(SUM(m.ItemPrice * o.Quantity), 0) as TotalEstimate
        FROM ReservationRecord r
        JOIN CustomerTable c ON r.TableNumber = c.TableNumber
        LEFT JOIN OrderItems o ON r.ReservationID = o.ReservationID
        LEFT JOIN MenuServices m ON o.MenuID = m.MenuID
        GROUP BY r.ReservationID
    `;
    db.query(query, (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

// --- PAYMENTS & INVOICES ---
app.post('/api/payments', (req, res) => {
    const { reservationId, amountPaid, paymentDate } = req.body;
    db.query('INSERT INTO Payment (ReservationID, AmountPaid, PaymentDate) VALUES (?, ?, ?)', [reservationId, amountPaid, paymentDate], (err) => {
        if (err) return res.status(500).json({ error: err.message });
        db.query('UPDATE ReservationRecord SET Status = "Paid" WHERE ReservationID = ?', [reservationId], () => {
            res.json({ message: 'Payment recorded' });
        });
    });
});

app.get('/api/invoice/:reservationId', (req, res) => {
    const { reservationId } = req.params;
    const infoQuery = `
        SELECT r.ReservationID, r.TableNumber, r.VisitDate, c.CustomerName, c.Phone, c.WaiterName
        FROM ReservationRecord r
        JOIN CustomerTable c ON r.TableNumber = c.TableNumber
        WHERE r.ReservationID = ?
    `;
    const itemsQuery = `
        SELECT m.ItemName, m.ItemPrice, o.Quantity, (m.ItemPrice * o.Quantity) AS SubTotal
        FROM OrderItems o
        JOIN MenuServices m ON o.MenuID = m.MenuID
        WHERE o.ReservationID = ?
    `;
    db.query(infoQuery, [reservationId], (err, infoRes) => {
        if (err || infoRes.length === 0) return res.status(404).json({ message: 'Not found' });
        db.query(itemsQuery, [reservationId], (err, itemsRes) => {
            res.json({ meta: infoRes[0], items: itemsRes });
        });
    });
});

// --- DAILY REPORTS ---
app.get('/api/reports/daily', (req, res) => {
    const today = new Date().toISOString().split('T')[0];
    const tablesQuery = `
        SELECT r.ReservationID, r.TableNumber, c.CustomerName, c.WaiterName, p.AmountPaid
        FROM ReservationRecord r
        JOIN CustomerTable c ON r.TableNumber = c.TableNumber
        JOIN Payment p ON r.ReservationID = p.ReservationID
        WHERE p.PaymentDate = ?
    `;
    db.query(tablesQuery, [today], (err, tables) => {
        db.query('SELECT SUM(AmountPaid) AS TotalRevenue FROM Payment WHERE PaymentDate = ?', [today], (err, revResult) => {
            res.json({ date: today, tablesServed: tables, totalRevenue: revResult[0].TotalRevenue || 0 });
        });
    });
});

app.listen(PORT, () => console.log(`Server executing smoothly on port ${PORT}`));