const TransactionDetail = require("../models/TransactionDetail");
const Expense = require("../models/Expense");
const Order=require('../models/Order')
const Branch = require("../models/Branch");
const BankTransaction = require("../models/BankTransaction");
const { get_TodaySales } = require('./dailySalesController');
const { get_MonthlyExpenses} =require('./monthlyExpenseController');
const Company = require("../models/Company");
const Transaction = require("../models/Transaction");
exports.getTotalSummary = async (req, res) => { // daily summary: at the time of request calculate adrgo return yadergal
  const companyId = req.query.companyId;
  const branchId = req.query.branchId;

  try {
    // Get the current date
    let startDate = new Date();
    let endDate = new Date();

    // Set the start and end of the day in UTC
    startDate = new Date(startDate.setUTCHours(0, 0, 0, 0));  // Start of the day
    endDate = new Date(endDate.setUTCHours(23, 59, 59, 999));  // End of the day

    // Fetch all transactions for the given companyId and filter by the current UTC date
    const transactions = await TransactionDetail.find({
      companyId,branchId ,
      createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
    });

    // Initialize totals
    let totalSales = 0;
    let totalPurchases = 0;
    let totalExpense = 0;
    let bankDeposit = 0;
    let bankWithdraw = 0;
    let toDaySale=0;
    // Calculate total sales and purchases
    transactions.forEach(transaction => {
      if (transaction.transactionType === 'selling') {
        totalSales += transaction.total;
      } else if (transaction.transactionType === 'purchasing') {
        totalPurchases += transaction.total;
      }
    });

    // Fetch all expenses for the given companyId and filter by current UTC date
    const expenses = await Expense.find({
      companyId,branchId ,
      createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
    });

    // Calculate total expenses
    expenses.forEach(expense => {
      totalExpense += expense.amount;
    });

    // Fetch all bank transactions for the given companyId and filter by current UTC date
    const bankTransactions = await BankTransaction.find({
      companyId,branchId ,
      createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
    });

    // Calculate total deposits and withdrawals
    bankTransactions.forEach(transaction => {
      if (transaction.transactionType === 'deposit') {
        bankDeposit += transaction.amount;
      } else if (transaction.transactionType === 'withdrawal') {
        bankWithdraw += transaction.amount;
      }
    });


    toDaySale = await get_TodaySales(companyId, branchId, new Date());

  //  console.log("to day sale is:"+toDaySale);
    // Send the calculated totals as a response


  



    res.status(200).json({
        message: 'Totals calculated successfully',
        totalSales,
        totalPurchases,
        totalExpense,
        bankDeposit,
        bankWithdraw,
        toDaySale ,
      
      });
      
  } catch (error) {
    console.error('Error calculating totals:', error);
    res.status(500).json({ message: 'Error calculating totals', error });
  }
};


exports.get_Total_Summary = async (companyId,branchId,start,end) => {
    try {
      // Get the current date

      let date1=start||new Date();
      let date2=end||date1;// if end date is not provided it will do only for one given day wich is start day

      let startDate = new Date(date1);
      let endDate = new Date(date2);
  
      // Set the start and end of the day in UTC
      startDate = new Date(startDate.setUTCHours(0, 0, 0, 0));  // Start of the day
      endDate = new Date(endDate.setUTCHours(23, 59, 59, 999));  // End of the day
  
   //   console.log("start",startDate);
     // console.log("end",endDate);
      // Fetch all transactions for the given companyId and filter by the current UTC date
    const currentBranch=await Branch.findById(branchId);

      const transactionDetail = await TransactionDetail.find({
       companyId,branchId,
        createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
      });
   

      const company = await Company.findOne({ _id: companyId });
      const shopType = company?.shopType || 'retail'; // Default to 'retail' if shopType is undefined or null
    
      let totalSales = 0;
      let totalStoreWithdrawal = 0;
      let stockDeductedForSelling=0;
      let totalPurchases = 0;
      let totalExpense = 0;
      let bankDeposit = 0;
      let bankWithdraw = 0;
      let toDaySale=0;
      let totalGrowthProfit=0;// for normal shop not for bakery

      let cash=0;
      let bank=0;
      let credit=0;
      let other=0;
     
      // Calculate total sales and purchases
      transactionDetail .forEach(transaction => {
        //console.log("shop type is",branchType, transaction.transactionType)
        
       
        
         if (transaction.transactionType === 'selling') { // ordering will not be included in transaction here. it will be considered in other places

           totalSales += transaction.total;// sales with or with out profit total= selling price * quantity
            totalGrowthProfit+=transaction.profit;// 

            stockDeductedForSelling+=(transaction.avg_price)*(transaction.quantity);// material or stock taken during selling
         }
        else  if (transaction.transactionType === 'purchasing') {
           totalPurchases += transaction.total;
        }
    
        else  if(transaction.transactionType === 'using')
         {
        
       
          totalStoreWithdrawal+=(transaction.avg_price)*(transaction.quantity);// material or stock taken  from store
        }

        else{
         //
        }

      }); 
     
   
     

      const orders = await Order.find({
        companyId,
        branchId,
        createdAt: { $gte: startDate, $lte: endDate },
      });  // this only refers to the ordering date not necessary today it is to calculate advance payment at that day. but for remaining paid it shall be for today
      
      // Calculate totalAdvancePayment for all orders of today
      const advancePayment = orders.reduce(
        (sum, order) => sum + order.advancePayment,
        0
      );
      // for today
      // Calculate totalRemainingPayment only for orders with status = true // means  already paid
    
      let remainingPayment=0; // all remaining payments paid today(at given date)
      
    const all_transaction = await Transaction.find({
      companyId,
      branchId,
      createdAt: { $gte: startDate, $lte: endDate },
    }).populate('orderId').populate("paymentId");  


    all_transaction.forEach(transaction => {

      if (transaction.transactionType === 'ordering') {
      remainingPayment=remainingPayment+transaction.orderId.remainingPayment;// this will not be used to calculate profit its use only to control daiy cash
      }

    else  if (transaction.transactionType === 'selling') {

      

         cash += transaction.paymentId?.cash ?? 0;
        bank+= transaction.paymentId?.bank ?? 0;
        credit+= transaction.paymentId?.credit ?? 0;
        other+= transaction.paymentId?.other ?? 0;



      }

    });

      // const remainingPayment = orders
      //   .filter(order => order.status === true) // Only include orders with status = true
      //   .reduce((sum, order) => sum + order.remainingPayment, 0);
      


      // console.log('Total Advance Payment:', advancePayment);// paid today
      // console.log('Total Remaining Payment:', remainingPayment);//paid today

      const orderPayments=advancePayment+remainingPayment;
  
      // Fetch all expenses for the given companyId and filter by current UTC date
      const expenses = await Expense.find({
        companyId,branchId,
        createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
      });
  
      // Calculate total expenses
      expenses.forEach(expense => {
        totalExpense += expense.amount;
      });
  
      // Fetch all bank transactions for the given companyId and filter by current UTC date
      const bankTransactions = await BankTransaction.find({
        companyId,branchId,
        createdAt: { $gte: startDate, $lte: endDate }  // Filter by today's UTC date
      });
  
      // Calculate total deposits and withdrawals
      bankTransactions.forEach(transaction => {
        if (transaction.transactionType === 'deposit') {
          bankDeposit += transaction.amount;
        } else if (transaction.transactionType === 'withdrawal') {
          bankWithdraw += transaction.amount;
        }
      });
  
   
     
     
      toDaySale = await get_TodaySales(companyId, branchId, startDate,endDate); // cashier sale



      const start1 = new Date(startDate);
      const end1 = new Date(endDate);
  
      // Set time to midnight to avoid issues with time components
      start1.setHours(0, 0, 0, 0);
      end1.setHours(0, 0, 0, 0);
  
      const diffInMs = Math.abs(end1 - start1);
      const days = Math.ceil(diffInMs / (1000 * 60 * 60 * 24));// 
     
      const expensePerDay=(await get_MonthlyExpenses(companyId, branchId))*days;// just multiplying by date intrval
       
      console.log(" expense per day",expensePerDay)
      
       let dailyNetProfit=0;
       let dailyNetProfitUsingSystem=0;
       let dailyNetProfitUsingCashier=0;
        
       if(shopType==="manufacturing"){ 
      
        dailyNetProfitUsingSystem= totalSales+orderPayments-totalStoreWithdrawal-totalExpense-expensePerDay;// only for manufacturing like bakery, totalsale means system sale 
       
        dailyNetProfitUsingCashier= toDaySale+orderPayments- totalStoreWithdrawal-totalExpense-expensePerDay;// only for manufacturing like bakery, todaysale means cashier sale 
                  
        const condition4=currentBranch.considerSystemWithdrawalForSelling;// for selling or ordering
    // condition 4 is considering selling items as stock deducted
     if(condition4){
      dailyNetProfitUsingSystem= dailyNetProfitUsingSystem-stockDeductedForSelling;
      dailyNetProfitUsingCashier=  dailyNetProfitUsingCashier-stockDeductedForSelling;


     }

    

      }
            
    else {   // depened on system profit record

          dailyNetProfitUsingSystem=totalGrowthProfit-totalExpense-expensePerDay; // for normal shop           
          dailyNetProfitUsingCashier= toDaySale+orderPayments- stockDeductedForSelling-totalExpense-expensePerDay;//for normal shop   
      
        }
console.log("daily total sales is", totalSales)
console.log("daily total advances payment and remaining paymnet is",advancePayment,remainingPayment);
       totalSales=totalSales+advancePayment+remainingPayment;// this is the total amount of sales and advance payments and remaining orders are amount of advance payments
       
       // Return the totals
      return {
        totalSales, // including advance payments and remaining order payments
        totalStoreWithdrawal,
        totalPurchases,
        totalExpense,
        bankDeposit,
        bankWithdraw,
        toDaySale,
        dailyNetProfitUsingSystem,
        dailyNetProfitUsingCashier,
        orderAdvance:advancePayment,
        orderRemaining:remainingPayment,// from ordering
        cash,bank,credit,other,
        totalStoreWithdrawalForSelling:stockDeductedForSelling,
      };
    } catch (error) {
      console.error('Error calculating summaries:', error);
      throw error;
    }
  };