const Product = require('../models/product');
const Warehouse = require('../models/Warehouse');
const StockTransaction = require('../models/StockTransaction');

function applyTransaction(product, transactionType, quantity, reverse = false) {
  const qty = Number(quantity);
  if (reverse) {
    if (transactionType === 'Stock In') {
      product.quantityInStock = Math.max(0, product.quantityInStock - qty);
    } else {
      product.quantityInStock += qty;
    }
  } else {
    if (transactionType === 'Stock In') {
      product.quantityInStock += qty;
    } else {
      product.quantityInStock = Math.max(0, product.quantityInStock - qty);
    }
  }
}

exports.addsales = async (req, res) => {
  try {
    const { transactionDate, quantityMoved, transactionType, productId, warehouseId } = req.body;

    const product = await Product.findById(productId);
    if (!product) {
      return res.status(404).json({ msg: 'Product not found' });
    }

    const warehouse = await Warehouse.findById(warehouseId);
    if (!warehouse) {
      return res.status(404).json({ msg: 'Warehouse not found' });
    }

    const newsales = await StockTransaction.create({
      transactionDate,
      quantityMoved,
      transactionType,
      product: productId,
      warehouse: warehouseId,
    });

    applyTransaction(product, transactionType, quantityMoved);
    await product.save();

    res.status(201).json({ msg: 'Transaction added successfully', transaction: newsales });
  } catch (error) {
    res.status(500).json({ msg: 'Failed to add transaction', error: error.message });
  }
};

exports.getsales = async (req, res) => {
  try {
    const getsales = await StockTransaction.find().populate('product warehouse');
    res.status(200).json(getsales);
  } catch (error) {
    res.status(404).json({ msg: 'Transactions not found' });
  }
};

exports.getsalesbyid = async (req, res) => {
  try {
    const getsalesbyid = await StockTransaction.findById(req.params.id).populate('product warehouse');
    if (!getsalesbyid) {
      return res.status(404).json({ msg: 'Transaction not found' });
    }
    res.status(200).json(getsalesbyid);
  } catch (error) {
    res.status(404).json({ msg: 'Failed to fetch' });
  }
};

exports.updatesales = async (req, res) => {
  try {
    const transaction = await StockTransaction.findById(req.params.id);
    if (!transaction) return res.status(404).json({ msg: 'Transaction not found' });

    const oldProduct = await Product.findById(transaction.product);
    if (oldProduct) {
      applyTransaction(oldProduct, transaction.transactionType, transaction.quantityMoved, true);
      await oldProduct.save();
    }

    const { transactionDate, quantityMoved, transactionType, productId, warehouseId } = req.body;
    const newProduct = await Product.findById(productId);
    if (!newProduct) {
      return res.status(404).json({ msg: 'Product not found' });
    }

    applyTransaction(newProduct, transactionType, quantityMoved);
    await newProduct.save();

    transaction.transactionDate = transactionDate;
    transaction.quantityMoved = quantityMoved;
    transaction.transactionType = transactionType;
    transaction.product = productId;
    transaction.warehouse = warehouseId;
    await transaction.save();

    const updatesales = await StockTransaction.findById(req.params.id).populate('product warehouse');
    res.status(200).json(updatesales);
  } catch (error) {
    res.status(500).json({ msg: 'Failed to update', error: error.message });
  }
};

exports.deletesales = async (req, res) => {
  try {
    const transaction = await StockTransaction.findById(req.params.id);
    if (!transaction) return res.status(404).json({ msg: 'Transaction not found' });

    const product = await Product.findById(transaction.product);
    if (product) {
      applyTransaction(product, transaction.transactionType, transaction.quantityMoved, true);
      await product.save();
    }

    await transaction.deleteOne();
    res.status(200).json({ msg: 'Deleted successfully' });
  } catch (error) {
    res.status(500).json({ msg: 'Failed to delete', error: error.message });
  }
};