import StockTransaction from '../models/StockTransaction.js';
import Product from '../models/Product.js';

const createTransaction = async (req, res) => {
  try {
    const { product, warehouse, transactionDate, quantityMoved, transactionType } = req.body;

    if (!product || !warehouse || !quantityMoved || !transactionType) {
      return res.status(400).json({ message: 'All fields are required' });
    }

    if (!['Stock In', 'Stock Out'].includes(transactionType)) {
      return res.status(400).json({ message: 'Transaction type must be "Stock In" or "Stock Out"' });
    }

    const productExists = await Product.findById(product);

    if (!productExists) {
      return res.status(404).json({ message: 'Product not found' });
    }

    if (transactionType === 'Stock Out') {
      if (productExists.quantityInStock < quantityMoved) {
        return res.status(400).json({
          message: `Insufficient stock. Available: ${productExists.quantityInStock}`
        });
      }
      productExists.quantityInStock -= quantityMoved;
    } else {
      productExists.quantityInStock += quantityMoved;
    }

    await productExists.save();

    const transaction = await StockTransaction.create({
      product,
      warehouse,
      transactionDate: transactionDate || Date.now(),
      quantityMoved,
      transactionType,
    });

    const populatedTransaction = await StockTransaction.findById(transaction._id)
      .populate('product')
      .populate('warehouse');

    res.status(201).json(populatedTransaction);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

const getAllTransactions = async (req, res) => {
  try {
    const transactions = await StockTransaction.find({})
      .populate('product')
      .populate('warehouse');
    res.json(transactions);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

const getSingleTransaction = async (req, res) => {
  try {
    const transaction = await StockTransaction.findById(req.params.id)
      .populate('product')
      .populate('warehouse');

    if (!transaction) {
      return res.status(404).json({ message: 'Transaction not found' });
    }

    res.json(transaction);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

const updateTransaction = async (req, res) => {
  try {
    const { quantityMoved, transactionType } = req.body;

    const transaction = await StockTransaction.findById(req.params.id)
      .populate('product')
      .populate('warehouse');

    if (!transaction) {
      return res.status(404).json({ message: 'Transaction not found' });
    }

    const product = await Product.findById(transaction.product._id);

    if (!product) {
      return res.status(404).json({ message: 'Product not found' });
    }

    const oldQuantity = transaction.quantityMoved;
    const oldType = transaction.transactionType;

    if (oldType === 'Stock In') {
      product.quantityInStock -= oldQuantity;
    } else {
      product.quantityInStock += oldQuantity;
    }

    if (transactionType === 'Stock Out') {
      if (product.quantityInStock < quantityMoved) {
        return res.status(400).json({
          message: `Insufficient stock. Available: ${product.quantityInStock}`
        });
      }
      product.quantityInStock -= quantityMoved;
    } else {
      product.quantityInStock += quantityMoved;
    }

    await product.save();

    transaction.quantityMoved = quantityMoved;
    transaction.transactionType = transactionType;
    transaction.transactionDate = req.body.transactionDate || transaction.transactionDate;
    transaction.warehouse = req.body.warehouse || transaction.warehouse._id;

    await transaction.save();

    const updatedTransaction = await StockTransaction.findById(transaction._id)
      .populate('product')
      .populate('warehouse');

    res.json(updatedTransaction);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

const deleteTransaction = async (req, res) => {
  try {
    const transaction = await StockTransaction.findById(req.params.id);

    if (!transaction) {
      return res.status(404).json({ message: 'Transaction not found' });
    }

    const product = await Product.findById(transaction.product);

    if (!product) {
      return res.status(404).json({ message: 'Product not found' });
    }

    if (transaction.transactionType === 'Stock In') {
      product.quantityInStock -= transaction.quantityMoved;
    } else {
      product.quantityInStock += transaction.quantityMoved;
    }

    if (product.quantityInStock < 0) {
      product.quantityInStock = 0;
    }

    await product.save();

    await StockTransaction.findByIdAndDelete(req.params.id);

    res.json({ message: 'Transaction deleted successfully' });
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

export { createTransaction, getAllTransactions, getSingleTransaction, updateTransaction, deleteTransaction };
