const { Tanker, Tankerbooking,Bore,GovtPipeLine,UserSupplierAccounts } = require('../models/tankers')
const { User,Counter, generateBookingId,resetCounter,generateCustomerId } = require('../models/User')

const { Supplier, generateSupplierId, FriendRequest,DeliveryBoy} = require("../models/supplier")

//const User = require("../models/User");
const boom = require("boom");


const fastify = require("fastify")({
  logger: true,
});




exports.addTankers = async (req, reply) => {
  try {

    //const username = req.params.username;

  console.log(req.params);
    const supplierId = req.params.supplierId;
    //console.log(loginObject.user.username)
    // const userInfo = await User.findOne({ username: username.toString() });
    // const updateData = req.body;
    

    // console.log("This is the reply in the handler after the validations", reply);
    tankersData = {
      supplierId:supplierId,

      supplier_name:req.body.supplier_name,
      supplier_address : req.body.supplier_address,
      tankerName: req.body.tankerName,
      phoneNumber: req.body.phoneNumber,
      alternative_phoneNumber: req.body.alternative_phoneNumber,
      typeofwater: req.body.typeofwater,
      capacity: req.body.capacity,
      price: req.body.price,
      status: req.body.status
    };
   console.log(req.body.typeofwater,req.body.capacity)

    var tanker_Name = req.body.tankerName
    var i_tank = await Tanker.findOne({ tankerName: tanker_Name,supplierId:supplierId})
    if(i_tank){
    throw new Error('tankername already exists');
            }
  else {

    var tankers = new Tanker(tankersData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
      usertobeInserted = checkFormEncoding.tankers;
      console.log("thsi true url string");
      tankers.supplier_name = usertobeInserted.supplier_name;
      tankers.supplier_address = usertobeInserted.supplier_address;
      tankers.tankerName = usertobeInserted.tankerName;
      tankers.phoneNumber = usertobeInserted.phoneNumber;
      tankers.alternative_phoneNumber = usertobeInserted.alternative_phoneNumber;
      tankers.capacity = usertobeInserted.capacity;
      tankers.typeofwater = usertobeInserted.typeofwater;
      tankers.price = usertobeInserted.price;
      tankers.status = usertobeInserted.status;
    }
  }
    const insertedTanker = await tankers.save();

    return insertedTanker;
  

  } catch (err) {
    throw boom.boomify(err);
  }
};




exports.deleteTankerInfo1 = async (req, reply) => {
  try {

    //const username = req.params.username;

console.log(req.params);
    const supplierId = req.params.supplierId;
    //console.log(loginObject.user.username)
    // const userInfo = await User.findOne({ username: username.toString() });
    // const updateData = req.body;
    

    // console.log("This is the reply in the handler after the validations", reply);
    tankersData = {
      supplierId:supplierId,

      supplier_name:req.body.supplier_name,
      supplier_address : req.body.supplier_address,
      tankerName: req.body.tankerName,
      phoneNumber: req.body.phoneNumber,
      alternative_phoneNumber: req.body.alternative_phoneNumber,
      typeofwater: req.body.typeofwater,
      capacity: req.body.capacity,
      price: req.body.price,
      status: req.body.status
    };
   console.log(req.body.typeofwater,req.body.capacity)

    var tanker_Name = req.body.tankerName
    var i_tank = await Tanker.findOne({ tankerName: tanker_Name,supplierId:supplierId})
    if(i_tank){
    throw new Error('tankername already exists');
            }
  else {

    var tankers = new Tanker(tankersData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
      usertobeInserted = checkFormEncoding.tankers;
      console.log("thsi true url string");
      tankers.supplier_name = usertobeInserted.supplier_name;
      tankers.supplier_address = usertobeInserted.supplier_address;
      tankers.tankerName = usertobeInserted.tankerName;
      tankers.phoneNumber = usertobeInserted.phoneNumber;
      tankers.alternative_phoneNumber = usertobeInserted.alternative_phoneNumber;
      tankers.capacity = usertobeInserted.capacity;
      tankers.typeofwater = usertobeInserted.typeofwater;
      tankers.price = usertobeInserted.price;
      tankers.status = usertobeInserted.status;
    }
  }
    const insertedTanker = await tankers.save();

    return insertedTanker;
  

  } catch (err) {
    throw boom.boomify(err);
  }
};

//update selected tanker
exports.updateTankersInfo = async (req, reply) =>  {

  try {
    var supplierId = req.params.supplierId;
    var tankerName = req.query.tankerName;
    var tanker = req.body;
    const { ...updateData } = tanker;
    const update = await Tanker.findOneAndUpdate({ supplierId:supplierId,tankerName: tankerName, }, updateData, { new: true });
    //console.log(update.username)
    //return update;

    reply.send({ status_code: 200, data: update });


  } 
  catch (err) {
    throw boom.boomify(err);
  }
};

//delete selected tanker
exports.deleteTankerInfo = async (req, reply) => {
  try {
    var supplierId = req.params.supplierId;
    var tankerName = req.query.tankerName;
    const tanker = await Tanker.findOneAndDelete({ supplierId:supplierId,tankerName: tankerName, });
    reply.send({ status_code: 200, data: tanker});
   // return tanker;
  } catch (err) {
    throw boom.boomify(err);
  }
};

exports.tankerBooking = async (req, reply) => {

  try {
    const customerId = req.params.customerId;
    const tankerName = req.body.tankerName;
    var b_id = await generateBookingId()
    const date = new Date()
    const year = date.getFullYear()
    const month = (date.getMonth() + 1).toString().padStart(2, '0')
    const day = date.getDate().toString().padStart(2, '0')
    const bookingId = `ARM${year}${month}${day}${b_id}`
    // const customer = await User.findOne({customerId:customerId})
    // const customer_mobile = customer.phone
    // const customer_name = customer.username
    // const supplier = await Supplier.findOne({supplierId:req.body.supplierId}) 
    // console.log(supplier, "11")
    // const supplier_name = supplier.suppliername
    // const supplier_mobile = supplier.phone
    // console.log(supplier_mobile, "==========")

    const customer = await User.findOne({customerId:customerId})
    const customerPhone = customer.phone
    const customerName = customer.username
    const supplier = await Supplier.findOne({supplierId:req.body.supplierId}) 
    const supplierName = supplier.suppliername
    const supplierPhone = supplier.phone
    var booking_id = await Tankerbooking.findOne({ bookingid: bookingId})
    if(booking_id){
      b_id= await generateBookingId()
           }
   else {
    
   
    bookingsData = {
      tankerName:tankerName,
      customerId:customerId,
      bookingid : bookingId,
      typeofwater: req.body.typeofwater,
      capacity: req.body.capacity,
      address: req.body.address,
      dateOfOrder: req.body.dateOfOrder,
      price:req.body.price,
      supplierId:req.body.supplierId,
      tankName:req.body.tankName,
      tankLocation:req.body.tankLocation,
     latitude: req.body.latitude,
     longitude: req.body.longitude,
     //date: req.body.date,
     // time: req.body.time,
      customerPhone  : customerPhone,
      supplierPhone  : supplierPhone,
      customerName  : customerName,
      supplierName  : supplierName,

    };
 
    var tankersBookingData = new Tankerbooking(bookingsData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
      usertobeInserted = checkFormEncoding.tankersBookingData;
      console.log("thsi true url string");
      tankersBookingData.customerId = customerId;
      tankersBookingData.tankerName = tankerName;
      tankersBookingData.bookingid = bookingId;
      tankersBookingData.capacity = usertobeInserted.capacity;
      tankersBookingData.typeofwater = usertobeInserted.typeofwater;
      tankersBookingData.address = usertobeInserted.address;
      tankersBookingData.dateOfOrder = usertobeInserted.dateOfOrder;
      tankersBookingData.price = usertobeInserted.price;
      tankersBookingData.supplierId = usertobeInserted.supplierId;
      tankersBookingData.tankName = usertobeInserted.tankName;
      tankersBookingData.tankLocation = usertobeInserted.tankLocation;
     //tankersBookingData.date = usertobeInserted.date;
      //tankersBookingData.time = usertobeInserted.time;
      tankersBookingData.customerPhone  = customerPhone;
      tankersBookingData.supplierPhone  = supplierPhone;
      tankersBookingData.customerName  = customerName;
      tankersBookingData.supplierName  = supplierName;
     tankersBookingData.latitude =usertobeInserted.latitude
     tankersBookingData.longitude=usertobeInserted.longitude

    }
  }
  
    const booking_data = await tankersBookingData.save();
    reply.send({ status_code: 200, data: booking_data });

    return booking_data;
    
  

  } catch (err) {
    throw boom.boomify(err);
  }
};

exports.getTanker = async (req, reply) => {
  try {
    await Tanker.find({supplierId: req.query.supplierId})
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};

exports.getallTanker = async (req, reply) => {
  try {
    await Tanker.find()
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};






exports.getTankersBookingdetails = async (req, reply) => {
  try {
    const customerId = req.params.customerId
    const tankerName = req.query.tankerName

    await Tankerbooking.find({ customerId:customerId,tankerName: tankerName, })
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })



      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });


      
      
  } catch (err) {
    throw boom.boomify(err);
  }
};


exports.getAllTankersBookingdetails = async (req, reply) => {
  const limit = parseInt(req.query.limit) || 100;
  const page = parseInt(req.query.page) || 1;
  const startindex = (page - 1) * limit;
  const supplierId = req.params.supplierId
  try {
    await Tankerbooking.find( { supplierId:supplierId })
      .limit(limit)
      .skip(startindex)
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};



exports.getAllTankersaccepted = async (req, reply) => {
  const limit = parseInt(req.query.limit) || 100;
  const page = parseInt(req.query.page) || 1;
  const startindex = (page - 1) * limit;
  const supplierId = req.params.supplierId
  try {
    await Tankerbooking.find( { supplierId, orderStatus: ["accepted","rejected"] })
      .limit(limit)
      .skip(startindex)
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};



exports.addBores = async (req, reply) => {
  try {

   
    var customerId = req.params.customerId;
    //console.log(customerId);
    //const  username  = loginObject.user.username;
    
    boresData = {
     // InstallerId:InstallerId,
     // customerId:req.body.customerId,
     customerId:customerId,
      boreName: req.body.boreName,
      capacity: req.body.capacity,
      typeofwater: req.body.typeofwater,
      description: req.body.description,
    };
   

    var bore_Name = req.body.boreName
    var i_bore = await Bore.findOne({ boreName: bore_Name,customerId:customerId})
    if(i_bore){
    throw new Error('Bore already exists');
            }
  else {

    var bores = new Bore(boresData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
      usertobeInserted = checkFormEncoding.bores;
      console.log("thsi true url string");
      
     // bores.InstallerId = usertobeInserted.InstallerId

      bores.customerId = usertobeInserted.customerId
      bores.boreName = usertobeInserted.boreName;
      bores.capacity = usertobeInserted.capacity;     
      bores.typeofwater = usertobeInserted.typeofwater;
      bores.description = usertobeInserted.description;
    }
  }
    const insertedBore = await bores.save();

    return insertedBore;
  

  } catch (err) {
    throw boom.boomify(err);
  }
};

exports.getBores = async (req, reply) => {
  try {
    await Bore.find({customerId: req.query.customerId})
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};


exports.getBoresbyInstaller = async (req, reply) => {
  try {
    await Bore.find({InstallerId: req.query.InstallerId})
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};


exports.deleteBoresInfo = async (req, reply) => {
  try {
   
    
    await Bore.findOneAndDelete({customerId: req.params.customerId,boreName: req.query.boreName});
    //console.log(Bore)

    reply.send({ status_code: 200},);
   // return Bore;
  } catch (err) {
    throw boom.boomify(err);
  }
};


exports.updateBoresInfo = async (req, reply) => {

  try {
    var customerId = req.params.customerId;
    var boreName = req.query.boreName;
    const bore = req.body;
    const { ...updateData } = bore;
    const update = await Bore.findOneAndUpdate({ customerId:customerId,boreName: boreName, }, updateData, { new: true });
    //console.log(update.username)
    //return update;

    reply.send({ status_code: 200, data: update });


  } 
  catch (err) {
    throw boom.boomify(err);
  }
};


exports.addGovtPIpeline = async (req, reply) => {
  try {

   
    var customerId = req.params.customerId;
    //console.log(customerId);
    //const  username  = loginObject.user.username;
    
    pipelineData = {
      customerId:customerId,
      Name: req.body.Name,
      capacity: req.body.capacity,
      typeofwater: req.body.typeofwater,
      description: req.body.description,
    };
   

    var pipeline_Name = req.body.Name
    var i_pipe = await GovtPipeLine.findOne({ Name: pipeline_Name,customerId:customerId})
    if(i_pipe){
    throw new Error('Pipeline already exists');
            }
  else {

    var pipe_line = new GovtPipeLine(pipelineData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
      usertobeInserted = checkFormEncoding.pipe_line;
      console.log("thsi true url string");
      pipe_line.customerId = usertobeInserted.customerId
      pipe_line.Name = usertobeInserted.Name;
      pipe_line.capacity = usertobeInserted.capacity;       
      pipe_line.typeofwater = usertobeInserted.typeofwater;
      pipe_line.description = usertobeInserted.description;
    }
  }
    const insertedpipeline = await pipe_line.save();

    return insertedpipeline;
  

  } catch (err) {
    throw boom.boomify(err);
  }
};



exports.getPipeline = async (req, reply) => {
  try {
    await GovtPipeLine.find({customerId: req.query.customerId})
      .exec()
      .then((docs) => {
        reply.send({ status_code: 200, data: docs, count: docs.length });
      })
      .catch((err) => {
        console.log(err);
        reply.send({ error: err });
      });
  } catch (err) {
    throw boom.boomify(err);
  }
};



exports.deletePipelineInfo = async (req, reply) => {
  try {
   
    
    await GovtPipeLine.findOneAndDelete({customerId: req.params.customerId,Name: req.query.Name});
    //console.log(Bore)

    reply.send({ status_code: 200});
   // return Bore;
  } catch (err) {
    throw boom.boomify(err);
  }
}




exports.updatePipelineInfo = async (req, reply) => {

  try {
    var customerId = req.params.customerId;
    var Name = req.query.Name;
    const pipeline = req.body;
    const { ...updateData } = pipeline;
    const update = await GovtPipeLine.findOneAndUpdate({ customerId:customerId,Name: Name, }, updateData, { new: true });
    //console.log(update.username)
    //return update;

    reply.send({ status_code: 200, data: update });


  } 
  catch (err) {
    throw boom.boomify(err);
  }
};

exports.status = async (req, reply) => {

  try {
    var status = req.query.status;

    if (status === 'connected') {
      try {
        const tankers = await Tanker.find({});
        console.log("tankers...", tankers)
        reply.send(tankers);
      } catch (err) {
        reply.send({ message: err });
      }
    } else {
      reply.send({ message: 'Not Connected' });
    }

  } 
  catch (err) {
    throw boom.boomify(err);
  }
};

exports.connectionStatus = async (req, reply) => {
  try {
    // query the database to check if the customer and supplier are connected
    const isConnected = await User.findOne({ customerId: req.query.customerId })
      .populate('supplier', null, { supplierId: req.query.supplierId })
      .exec()
      .then(customer => customer.supplier !== null);

      console.log("isconne..", isConnected)
    
      if (isConnected) {
        // if customer and supplier are connected, return list of tankers
        const tankers = await Tanker.find({ }).exec();
        console.log("tankers..", tankers)
        reply.send({ tankers });
      } else {
        // if customer and supplier are not connected, return error
        reply.status(403).send({ error: 'Forbidden' });
      }
    //res.send({ tankers });
  } catch (err) {
    console.error(err);
    reply.status(500).send({ error: 'Internal server error' });
  }
}




exports.connectstatus = async (req, reply) => {

  try {
    const customerId = req.params.customerId;
    const supplierId = req.query.supplierId;
    
    console.log(req.params.customerId)
    console.log(req.query.supplierId)
    const data = await FriendRequest.findOne({ customerId: customerId, supplierId: supplierId });
    let connection_status = "not requested";
    if (data) {
      connection_status = data.status;
    }
    reply.send({ status_code: 200, customerId: customerId, supplierId: supplierId, status: connection_status });
  } catch (err) {
    throw boom.boomify(err);
  }
};




//delete selected bookingid
exports.deleteBookingInfo = async (req, reply) => {
  try {
    var bookingid = req.params.bookingid;
    
    const booking = await Tankerbooking.findOneAndDelete({ bookingid:bookingid });

    reply.send({ status_code: 200, data: booking});
   // return tank;
  } catch (err) {
    throw boom.boomify(err);
  }
};

exports.distrubanceStatus = async (req, reply) => {
  try {
    const bookingid = req.params.bookingid;
    const action = req.body.action
    const booking = await Tankerbooking.findOne({ bookingid:bookingid });
    const distrubance_price =  parseInt(booking.distrubance_price .replace(/,/g, ''), 10)
    const price =    parseInt(booking.price.replace(/,/g, ''), 10)
    const amount_due =  parseInt(booking.amount_due .replace(/,/g, ''), 10)
    const price_variation = price-distrubance_price       
    if (action === "accept") {
      await Tankerbooking.findOneAndUpdate({ bookingid:bookingid }, { $set: { amount_due: distrubance_price,amount_difference:price_variation},distrubance_status:"1" });

    }
    if (action === "reject") {


      await Tankerbooking.findOneAndUpdate({ bookingid:bookingid }, { $set: { amount_due: price,amount_difference:"0",distrubance_status:"0" } });

    }

    
    reply.send({ status_code: 200, data: booking});
   // return tank;
  } catch (err) {
    throw boom.boomify(err);
  }
};


exports.UserSupplierAccounts = async (req, reply) => {
  try {
    const customerId = req.params.customerId;
    const supplierId = req.body.supplierId
    const booking = await Tankerbooking.find({ customerId:customerId,supplierId:supplierId,orderStatus:"delivered"});
    const delivered_tankers = booking.length
    console.log(delivered_tankers, booking.length)
    let amount_due = 0
    let amount_advance = 0
    let TotalAmountPaid = 0
    for (let i = 0; i < booking.length; i++) {
      let order = booking[i];

        TotalAmountPaid +=   parseInt(order.amount_paid.replace(/,/g, ''), 10)
        amount_due +=    parseInt(order.amount_due.replace(/,/g, ''), 10)
      
    }
    
    console.log("TotalAmountPaid:", TotalAmountPaid);
    console.log("amount_due:", amount_due);

   const user_accounts = await UserSupplierAccounts.findOne({ customerId:customerId,supplierId:supplierId });
   if (user_accounts) {


    await UserSupplierAccounts.findOneAndUpdate({ customerId:customerId,supplierId:supplierId }, { $set: { amount_due: amount_due,amount_paid:TotalAmountPaid,delivered_tankers:delivered_tankers } });
  }
  else{

    UserSupplierData = {
      customerId:customerId,
      supplierId: supplierId,
      amount_due: amount_due,
      amount_paid: TotalAmountPaid,
      amount_advance: amount_advance,
      delivered_tankers:delivered_tankers
    };
   

    var user_supplier_accounts = new UserSupplierAccounts(UserSupplierData);

    checkFormEncoding = isUserFormUrlEncoded(req);
    if (checkFormEncoding.isUserFormUrlEncoded) {
     
      user_supplier_accounts.customerId = customerId
      user_supplier_accounts.supplierId = supplierId;
      user_supplier_accounts.amount_due = amount_due;       
      user_supplier_accounts.amount_paid = TotalAmountPaid;
      user_supplier_accounts.amount_advance = amount_advance;
      user_supplier_accounts.delivered_tankers = delivered_tankers;

    }
  
    const inserteduser_supplier_accounts_data = await user_supplier_accounts.save();


  }
    reply.send({ status_code: 200, count: booking.length, data: booking,TotalAmountPaid:TotalAmountPaid,amount_due:amount_due });  
 
  } catch (err) {
    throw boom.boomify(err);
  }
};

