const express = require('express');
const router = express.Router();
const Transaction = require('../models/Transaction');
const TransactionDetail = require('../models/TransactionDetail');
const BranchInventory= require('../models/BranchInventory');
const { getTransactionDetails } = require('../controllers/transactionDetailController');

// GET: Fetch all transactions
// GET: Fetch all transactions with optional filters for type, start date, end date, and companyId
router.get('/', async (req, res) => {
  try {
    const branchId = req.query.branchId;
    const companyId = req.query.companyId;
    const transactionType = req.query.transactionType?req.query.transactionType:"selling";
   
    let startDate = req.query.startDate ? new Date(req.query.startDate) : new Date(); // 
    let endDate = req.query.endDate ? new Date(req.query.endDate) : new Date(); // 
    startDate= new Date(startDate.setUTCHours(0,0,0,0));
    endDate= new Date(endDate.setUTCHours(23, 59, 59, 999));
 


 
    // Build the query based on filters
    const query = { branchId };

    
    // Add companyId filter if provided
    if (companyId) {
      query.companyId = companyId;
    }

    // Add transaction type filter if provided
    if (transactionType) {
      query.transactionType = transactionType;
    }
console.log("trans type:"+transactionType)
    // Add date range filter if both start and end dates are provided
    if (startDate && endDate) {
     query.createdAt = { $gte: startDate, $lte: endDate };
    }

    const transactions = await Transaction.find(query )
      // .populate('customerId') // Uncomment if you have a customerId to populate
    //  .sort({ createdAt: -1 }); // Sort by creation date

      console.log("res",transactions.length);

    res.json(transactions);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching transactions', error });
  }
});




router.get('/:transactionId/tr_details',getTransactionDetails)

// GET: Fetch transaction details by transaction ID
// GET: Fetch transaction details with filters for branchId, startDate, endDate, and transactionType
router.get('/tr_details', async (req, res) => {
  const { branchId, transactionType } = req.query;

  try {


    const today = new Date();
    const defaultStartDate = new Date(today.setUTCHours(0, 0, 0, 0)); // Start of today
    const defaultEndDate = new Date(today.setUTCHours(23, 59, 59, 999)); // End of today
   
    let startDate = req.query.startDate ? new Date(req.query.startDate ) : defaultStartDate;
   let endDate = req.query.endDate ? new Date( req.query.endDate) : defaultEndDate;
    
    
     startDate= new Date(startDate.setUTCHours(0,0,0,0));
     endDate= new Date(endDate.setUTCHours(23, 59, 59, 999));
  

    
    // Build the query based on the provided filters
    const query = { branchId };
    //const query = {  };
    // Add transaction type filter if provided
    if (transactionType) {
      query.transactionType = transactionType;
    }
   
    // Add date range filter if start and end dates are provided
    if (startDate && endDate) {
      query.createdAt = { $gte: new Date(startDate), $lte: new Date(endDate) };
    } 
   
    // Fetch transaction details based on the constructed query

  //console(query);
    const transactionDetails = await TransactionDetail.find(query);

    console.log(transactionDetails)
    res.json(transactionDetails);
  } catch (error) {
    res.status(500).json({ message: 'Error fetching transaction details', error });
  }
});

// PUT: Update a transaction (if editing functionality is needed)
router.put('/:id', async (req, res) => {
  const { id } = req.params;
  const updateData = req.body;

  try {
    const updatedTransaction = await Transaction.findByIdAndUpdate(id, updateData, { new: true });
    res.json(updatedTransaction);
  } catch (error) {
    res.status(500).json({ message: 'Error updating transaction', error });
  }
});

async function checkInventory(transactionDetails) {
  for (const detail of transactionDetails) {
    const { itemId, branchId, quantity } = detail;


      // Fetch branch inventory for the item
      const branchInventory = await BranchInventory.findOne({ branchId, itemId });
      if (!branchInventory) {
        return { success: false, message: `Branch inventory not found for itemId: ${itemId}` };
      }

      const balance = branchInventory.quantity; // Current inventory balance
     
      // Check if enough inventory is available before proceeding
      if (balance < quantity) {
        return { success: false, message: `Not enough inventory to return for itemId: ${itemId}. Available: ${balance}, Required: ${quantity}` };
      }
    
  }

  // If all checks pass, return success
  return { success: true };
}


// DELETE: Delete a transaction
router.delete('/:id', async (req, res) => {
  const { id } = req.params;
  const { transactionType } = req.query; // Get the transaction type from query parameters

  try {
    // Step 1: Fetch all transaction details related to this transaction
    const transactionDetails = await TransactionDetail.find({ transactionId: id });




  // Step 2: Check inventory before deletion
  if (transactionType === 'purchasing'||transactionType === 'producing') {
  const inventoryCheck = await checkInventory(transactionDetails, transactionType);
  if (!inventoryCheck.success) {
    return res.status(400).json({ message: inventoryCheck.message });
  }

  }


    // Step 2: Update branch inventory quantities based on transaction details
    for (const detail of transactionDetails) {
      const { itemId, branchId, quantity } = detail; // Assuming `branchId` is part of the transaction detail

    



      const branchInventory = await BranchInventory.findOne({ itemId, branchId });
    
   const balance=branchInventory.quantity;
      if (branchInventory) {
        // Adjust quantity based on transaction type
        let quantityChange;
        if (transactionType === 'selling'||transactionType === 'using') {
          // For selling, add back the quantity
          quantityChange = quantity;
        } else if (transactionType === 'purchasing'||transactionType === 'producing') {
          // For purchasing, subtract the quantity

          quantityChange = -quantity;
          // during purchsing delete the inventory balance shall be cheked befor procedding
          if (balance<quantityChange){
            return res.status(400).json({ message: 'There is no Enough Item to Return' });
    
          }
        } else {
          // Invalid transaction type
          return res.status(400).json({ message: 'Invalid transaction type' });
        }

        // Update branch inventory quantity
     
     
        await BranchInventory.updateOne(
          { _id: branchInventory._id },
          { $inc: { quantity: quantityChange } }
        );
      }
      
      else {
        console.log(`No branch inventory found for itemId: ${itemId}, branchId: ${branchId}`);
      }
    }

    // Step 3: Remove transaction details
    await TransactionDetail.deleteMany({ transactionId: id });
   

    // Step 4: Delete the transaction itself
    await Transaction.findByIdAndDelete(id);
    console.log("Transaction deleted");

    res.json({ success: true, message: 'Transaction deleted successfully and inventory updated' });
  } catch (error) {
    console.error('Error deleting transaction and updating inventory:', error);
    res.status(500).json({ message: 'Error deleting transaction and updating inventory', error });
  }
});





// DELETE: Delete a transaction
router.delete('/one/:id', async (req, res) => {
  const { id } = req.params;
  


  const { transactionType } = req.query; // Get the transaction type from query parameters

  try {
    // Step 1: Fetch transaction details related to this transaction
    const transactionDetails = await TransactionDetail.findOne({_id: id });

    // Step 2: Update branch inventory quantities based on transaction details
   
      const { itemId, branchId, quantity ,transactionId} =transactionDetails ; // Assuming `branchId` is part of the transaction detail

    

      const branchInventory = await BranchInventory.findOne({ itemId, branchId });
    

     
      const balance = branchInventory.quantity; // Current inventory balance
     




      if (branchInventory) {
        // Adjust quantity based on transaction type
        let quantityChange;
        if (transactionType === 'selling'||transactionType === 'using') {
          // For selling, add back the quantity
          quantityChange = quantity;
        } else if (transactionType === 'purchasing'||transactionType === 'producing') {
          // For purchasing, subtract the quantity
          quantityChange = -quantity;
       // Check if enough inventory is available before proceeding
            if (balance < quantity) {
              return res.status(400).json( { success: false, message: `Not enough inventory to return for itemId: ${itemId}. Available: ${balance}, Required: ${quantity}` });
            }

        } else {
          // Invalid transaction type
          return res.status(400).json({ message: 'Invalid transaction type' });
        }

        // Update branch inventory quantity
        await BranchInventory.updateOne(
          { _id: branchInventory._id },
          { $inc: { quantity: quantityChange } }
        );
      } else {
        console.log(`No branch inventory found for itemId: ${itemId}, branchId: ${branchId}`);
      }
    

    // Step 3: Remove transaction details
    await TransactionDetail.deleteOne({ _id: id });
   

    // // Step 4:updating the trasactio total items and total price

 // Fetch all transaction details for the main transaction
 const allTransactionDetails = await TransactionDetail.find({ transactionId });

 // Calculate updated totals
 const updatedTotalItems = allTransactionDetails.reduce((acc, detail) => acc + detail.quantity, 0);
 const updatedSubtotal = allTransactionDetails.reduce((acc, detail) => acc + detail.total, 0);

 // Update the main transaction
 await Transaction.findByIdAndUpdate(transactionId, {
   totalItems: updatedTotalItems,
   subtotal: updatedSubtotal,
   updatedAt: new Date(),
 });


    // await Transaction.findByIdAndDelete(id); if there is no record left
    // console.log("Transaction deleted");

    res.json({ success: true, message: 'Transaction deleted successfully and inventory updated' });
  } catch (error) {
    console.error('Error deleting transaction and updating inventory:', error);
    res.status(500).json({ message: 'Error deleting transaction and updating inventory', error });
  }
});


module.exports = router;
