import { Request, Response } from 'express';
import { Floor, Table } from '../models/Restaurant';

// --- Floos ---
export const getFloors = async (req: Request, res: Response) => {
    try {
        const floors = await Floor.find({});
        res.json(floors);
    } catch (error) {
        res.status(500).json({ message: 'Error fetching floors', error });
    }
};

export const createFloor = async (req: Request, res: Response) => {
    try {
        const { id, name } = req.body;
        const newFloor = new Floor({ id, name });
        await newFloor.save();
        res.status(201).json(newFloor);
    } catch (error) {
        res.status(500).json({ message: 'Error creating floor', error });
    }
};

export const updateFloor = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const { name } = req.body;
        const updatedFloor = await Floor.findOneAndUpdate({ id: Number(id) }, { name }, { new: true });
        res.json(updatedFloor);
    } catch (error) {
        res.status(500).json({ message: 'Error updating floor', error });
    }
};

export const deleteFloor = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        await Floor.findOneAndDelete({ id: Number(id) });
        // Also delete tables on this floor?
        await Table.deleteMany({ floorId: Number(id) });
        res.json({ message: 'Floor deleted' });
    } catch (error) {
        res.status(500).json({ message: 'Error deleting floor', error });
    }
};

// --- Tables ---
export const getTables = async (req: Request, res: Response) => {
    try {
        const tables = await Table.find({});
        // Map _id to id if frontend needs number id, but frontend seems to use number id.
        // We might need to handle the ID difference. 
        // For simple sync, let's just return what we have.
        // Frontend uses number IDs. We should probably stick to number IDs for simplicity if we want to match exactly, 
        // OR update frontend to use string _id.
        // Given existing frontend `initialTables` has `id: number`, I should probably also store `id: number` in TableSchema or just map it.
        // Let's modify the response to include `id` as `_id` or just pass `_id`.
        // The frontend expects `id`. 

        // Let's just update the Table Schema to also have a custom `id` field like Floor for consistency with existing frontend logic?
        // OR simpler: modify frontend to use _id.
        // modifying frontend to use _id is better long term.
        // But for now, to minimize friction, I will fetch tables.
        res.json(tables);
    } catch (error) {
        res.status(500).json({ message: 'Error fetching tables', error });
    }
};

export const createTable = async (req: Request, res: Response) => {
    try {
        const tableData = req.body;
        // if tableData has id, we can store it if we added it to schema.
        // Let's assume we want to store everything.
        const newTable = new Table(tableData);
        await newTable.save();
        res.status(201).json(newTable);
    } catch (error) {
        res.status(500).json({ message: 'Error creating table', error });
    }
};

export const updateTable = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        // This id is likely the Mongoose _id if we switch to it, or our custom id.
        // If frontend sends custom id number:
        const updates = req.body;

        // If we are using custom `id` field:
        const updatedTable = await Table.findOneAndUpdate({ id: Number(id) }, updates, { new: true });

        // If we use _id:
        // const updatedTable = await Table.findByIdAndUpdate(id, updates, { new: true });

        res.json(updatedTable);
    } catch (error) {
        res.status(500).json({ message: 'Error updating table', error });
    }
};

export const deleteTable = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        await Table.findOneAndDelete({ id: Number(id) });
        res.json({ message: 'Table deleted' });
    } catch (error) {
        res.status(500).json({ message: 'Error deleting table', error });
    }
};

// Special batch update for positions if needed, but updateTable works fine.

// --- Orders ---
import Order from '../models/Order';

export const createOrder = async (req: Request, res: Response) => {
    try {
        const orderData = req.body;
        const newOrder = new Order(orderData);
        await newOrder.save();
        res.status(201).json(newOrder);
    } catch (error) {
        console.error("Error creating order:", error);
        res.status(500).json({ message: 'Error creating order', error });
    }
};

export const getOrders = async (req: Request, res: Response) => {
    try {
        const { tableId, status, active } = req.query;
        const query: any = {};
        if (tableId) query.tableId = Number(tableId);
        if (status) query.status = status;
        if (active === 'true') query.status = { $ne: 'PAID' };

        const orders = await Order.find(query).sort({ createdAt: -1 });
        res.json(orders);
    } catch (error) {
        res.status(500).json({ message: 'Error fetching orders', error });
    }
};

export const settleTable = async (req: Request, res: Response) => {
    try {
        const { tableId } = req.params;
        const { paymentMethod, newItems, subtotal, tax, serviceCharge, total } = req.body;

        if (newItems && newItems.length > 0) {
            const closingOrder = new Order({
                tableId: Number(tableId),
                tableName: `Table ${tableId}`,
                items: newItems,
                subtotal,
                tax,
                serviceCharge,
                total,
                paymentMethod,
                status: 'PAID'
            });
            await closingOrder.save();
        }

        await Order.updateMany(
            { tableId: Number(tableId), status: { $ne: 'PAID' } },
            { $set: { status: 'PAID', paymentMethod } }
        );

        res.json({ message: 'Table settled' });
    } catch (error) {
        console.error("Settle error:", error);
        res.status(500).json({ message: 'Error settling table', error });
    }
};



// Update Order Status
export const updateOrderStatus = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const { status } = req.body;
        const updatedOrder = await Order.findByIdAndUpdate(id, { status }, { new: true });
        res.json(updatedOrder);
    } catch (error) {
        res.status(500).json({ message: 'Error updating order status', error });
    }
};

// Get Kitchen Orders
export const getKitchenOrders = async (req: Request, res: Response) => {
    try {
        const orders = await Order.find({ status: { $in: ['KITCHEN', 'READY', 'SERVED'] } }).sort({ createdAt: 1 });
        res.json(orders);
    } catch (error) {
        res.status(500).json({ message: 'Error fetching kitchen orders', error });
    }
};
