const express = require('express');
const pool = require('../config/db');
const authMiddleware = require('../middleware/auth');

const router = express.Router();

router.get('/', authMiddleware, async (req, res) => {
  try {
    const [transactions] = await pool.query(`
      SELECT st.*, p.productName, w.warehouseName
      FROM StockTransaction st
      JOIN Product p ON st.productCode = p.productCode
      JOIN Warehouse w ON st.warehouseCode = w.warehouseCode
      ORDER BY st.transactionDate DESC, st.transactionId DESC
    `);
    res.json(transactions);
  } catch (error) {
    res.status(500).json({ message: 'Failed to fetch transactions.', error: error.message });
  }
});

router.post('/', authMiddleware, async (req, res) => {
  const connection = await pool.getConnection();
  try {
    const { productCode, warehouseCode, transactionDate, quantityMoved, transactionType } = req.body;

    if (!productCode || !warehouseCode || !transactionDate || !quantityMoved || !transactionType) {
      return res.status(400).json({ message: 'All transaction fields are required.' });
    }

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

    await connection.beginTransaction();

    await connection.query(
      `INSERT INTO StockTransaction (productCode, warehouseCode, transactionDate, quantityMoved, transactionType)
       VALUES (?, ?, ?, ?, ?)`,
      [productCode, warehouseCode, transactionDate, quantityMoved, transactionType]
    );

    const stockChange = transactionType === 'IN' ? quantityMoved : -quantityMoved;
    const [result] = await connection.query(
      'UPDATE Product SET quantityInStock = quantityInStock + ? WHERE productCode = ?',
      [stockChange, productCode]
    );

    if (result.affectedRows === 0) {
      await connection.rollback();
      return res.status(404).json({ message: 'Product not found.' });
    }

    const [product] = await connection.query('SELECT quantityInStock FROM Product WHERE productCode = ?', [productCode]);
    if (product[0].quantityInStock < 0) {
      await connection.rollback();
      return res.status(400).json({ message: 'Insufficient stock for OUT transaction.' });
    }

    await connection.commit();
    res.status(201).json({ message: 'Transaction recorded successfully.' });
  } catch (error) {
    await connection.rollback();
    res.status(500).json({ message: 'Failed to add transaction.', error: error.message });
  } finally {
    connection.release();
  }
});

router.put('/:id', authMiddleware, async (req, res) => {
  const connection = await pool.getConnection();
  try {
    const { id } = req.params;
    const { productCode, warehouseCode, transactionDate, quantityMoved, transactionType } = req.body;

    const [existing] = await connection.query('SELECT * FROM StockTransaction WHERE transactionId = ?', [id]);
    if (existing.length === 0) {
      return res.status(404).json({ message: 'Transaction not found.' });
    }

    const oldTx = existing[0];
    await connection.beginTransaction();

    const oldChange = oldTx.transactionType === 'IN' ? -oldTx.quantityMoved : oldTx.quantityMoved;
    await connection.query(
      'UPDATE Product SET quantityInStock = quantityInStock + ? WHERE productCode = ?',
      [oldChange, oldTx.productCode]
    );

    await connection.query(
      `UPDATE StockTransaction SET productCode = ?, warehouseCode = ?, transactionDate = ?, quantityMoved = ?, transactionType = ?
       WHERE transactionId = ?`,
      [productCode, warehouseCode, transactionDate, quantityMoved, transactionType, id]
    );

    const newChange = transactionType === 'IN' ? quantityMoved : -quantityMoved;
    await connection.query(
      'UPDATE Product SET quantityInStock = quantityInStock + ? WHERE productCode = ?',
      [newChange, productCode]
    );

    const [product] = await connection.query('SELECT quantityInStock FROM Product WHERE productCode = ?', [productCode]);
    if (product[0].quantityInStock < 0) {
      await connection.rollback();
      return res.status(400).json({ message: 'Insufficient stock after update.' });
    }

    await connection.commit();
    res.json({ message: 'Transaction updated successfully.' });
  } catch (error) {
    await connection.rollback();
    res.status(500).json({ message: 'Failed to update transaction.', error: error.message });
  } finally {
    connection.release();
  }
});

router.delete('/:id', authMiddleware, async (req, res) => {
  const connection = await pool.getConnection();
  try {
    const { id } = req.params;

    const [existing] = await connection.query('SELECT * FROM StockTransaction WHERE transactionId = ?', [id]);
    if (existing.length === 0) {
      return res.status(404).json({ message: 'Transaction not found.' });
    }

    const tx = existing[0];
    await connection.beginTransaction();

    const stockChange = tx.transactionType === 'IN' ? -tx.quantityMoved : tx.quantityMoved;
    await connection.query(
      'UPDATE Product SET quantityInStock = quantityInStock + ? WHERE productCode = ?',
      [stockChange, tx.productCode]
    );

    await connection.query('DELETE FROM StockTransaction WHERE transactionId = ?', [id]);

    await connection.commit();
    res.json({ message: 'Transaction deleted successfully.' });
  } catch (error) {
    await connection.rollback();
    res.status(500).json({ message: 'Failed to delete transaction.', error: error.message });
  } finally {
    connection.release();
  }
});

module.exports = router;
