
import { Request, Response } from 'express';
import { InventoryItem } from '../models/Inventory';
import { InventoryTransaction } from '../models/InventoryTransaction';
import { createLowStockAlert } from '../services/alertService';

export const getInventory = async (req: Request, res: Response) => {
    try {
        // Inventory is currently global, not per-project in the model definition
        // If filtering is needed later, we can add it based on other criteria

        const inventory = await InventoryItem.find({}).sort({ createdAt: -1 });

        res.json({
            success: true,
            data: inventory
        });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const createInventoryItem = async (req: Request, res: Response) => {
    try {
        const { itemCode, name, category, unit, minStockLevel, location, supplierId, supplier, currentStock, unitCost } = req.body;

        // Basic validation
        if (!itemCode || !name || !category || !unit) {
            return res.status(400).json({ success: false, message: 'Missing required fields: itemCode, name, category, unit' });
        }

        // Check for duplicate itemCode
        const existingItem = await InventoryItem.findOne({ itemCode });
        if (existingItem) {
            return res.status(400).json({ success: false, message: 'Item code already exists' });
        }

        const newItem = new InventoryItem({
            itemCode,
            name,
            category,
            unit,
            minStockLevel: minStockLevel || 0,
            location,
            supplierId,
            supplier,
            currentStock: currentStock || 0,
            unitCost
        });

        await newItem.save();

        // Create alert if stock is low
        if (newItem.minStockLevel > 0 && newItem.currentStock <= newItem.minStockLevel) {
            await createLowStockAlert(
                newItem.name,
                newItem.itemCode,
                newItem.currentStock,
                newItem.minStockLevel,
                newItem._id.toString()
            );
        }

        res.status(201).json({
            success: true,
            data: newItem,
            message: 'Inventory item created successfully'
        });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const stockIn = async (req: Request, res: Response) => {
    try {
        const { itemId, quantity, unitCost, notes } = req.body;

        if (!itemId || quantity <= 0) {
            return res.status(400).json({ success: false, message: 'Invalid item ID or quantity' });
        }

        const item = await InventoryItem.findById(itemId);
        if (!item) {
            return res.status(404).json({ success: false, message: 'Item not found' });
        }

        item.currentStock += quantity;
        // Optionally update unitCost (averaging or last price) - for now just last price if provided
        if (unitCost > 0) item.unitCost = unitCost;

        await item.save();

        // Save Transaction
        const transaction = new InventoryTransaction({
            itemId,
            type: 'In',
            quantity,
            unitCost,
            notes,
            timestamp: new Date()
        });
        await transaction.save();

        res.json({ success: true, message: 'Stock in successful', data: item });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const stockOut = async (req: Request, res: Response) => {
    try {
        const { itemId, quantity, notes } = req.body;

        if (!itemId || quantity <= 0) {
            return res.status(400).json({ success: false, message: 'Invalid item ID or quantity' });
        }

        const item = await InventoryItem.findById(itemId);
        if (!item) {
            return res.status(404).json({ success: false, message: 'Item not found' });
        }

        if (item.currentStock < quantity) {
            return res.status(400).json({ success: false, message: 'Insufficient stock' });
        }

        item.currentStock -= quantity;
        await item.save();

        // Create alert if stock is low after stock out
        if (item.minStockLevel > 0 && item.currentStock <= item.minStockLevel) {
            await createLowStockAlert(
                item.name,
                item.itemCode,
                item.currentStock,
                item.minStockLevel,
                item._id.toString()
            );
        }

        // Save Transaction
        const transaction = new InventoryTransaction({
            itemId,
            type: 'Out',
            quantity,
            notes,
            timestamp: new Date()
        });
        await transaction.save();

        res.json({ success: true, message: 'Stock out successful', data: item });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const deleteInventoryItem = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;

        const item = await InventoryItem.findById(id);
        if (!item) {
            return res.status(404).json({ success: false, message: 'Item not found' });
        }

        // Optional: Check if item has transaction history before deleting?
        // For now, allow deletion.

        await InventoryItem.findByIdAndDelete(id);

        res.json({ success: true, message: 'Item deleted successfully' });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};

export const getInventoryHistory = async (req: Request, res: Response) => {
    try {
        const { itemId } = req.query;

        let query = {};
        if (itemId) {
            query = { itemId };
        }

        const history = await InventoryTransaction.find(query)
            .sort({ timestamp: -1 })
            .populate('itemId', 'name itemCode')
            .limit(100);

        res.json({ success: true, data: history });
    } catch (error: any) {
        res.status(500).json({ success: false, message: error.message });
    }
};
