const express = require("express");
const paypal = require('paypal-rest-sdk');
const flutterwave = require('flutterwave');
// const pesapal = require('pesapal-api');
const bodyParser = require("body-parser");
const pdf = require("html-pdf"); // Require the html-pdf library
const nodemailer = require("nodemailer"); // Require the nodemailer library
const fs = require("fs");

const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const flash = require('connect-flash');
const passport = require('passport');
const request = require('request');
const axios = require('axios');
const multer = require('multer');
 const puppeteer = require('puppeteer');
const path = require('path');

const session = require('express-session');

const methodOverride = require('method-override')
const router = express.Router();
var https = require('follow-redirects').https;

const moment = require('moment');
const bcrypt = require('bcryptjs');
var convert = require('color-convert');

const today = moment();
const util = require('util');
const app = express()

app.use(express.json())

app.use(bodyParser.json());

const User = require('./models/User');
const Email = require('./models/Email');
const Company = require('./models/Company');
const Agreement = require('./models/Agreement');
// Passport Config
require('./config/passport')(passport);

 // DB Config
const db = require('./config/keys').mongoURI;
// Connect flash
app.use(flash());

// Set static folder
app.use(express.static("public"));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));


// Connect to MongoDB
mongoose.set('strictQuery', false);
mongoose
  .connect(
    db,
    { useNewUrlParser: true ,useUnifiedTopology: true}
  )
  .then(() => console.log('MongoDB Connected'))
  .catch(err => console.log(err));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(methodOverride("_method"));

// EJS

app.use(express.static("public"));
app.set('view engine', 'ejs');

// Express body parser
app.use(express.urlencoded({ extended: true }));
const rooms = { }

// Express session
app.use(
  session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
  })
);

// Passport middleware
app.use(passport.initialize());
app.use(passport.session());

var currentDate = new Date();



// Global variables
app.use(function(req, res, next) {
  res.locals.success_msg = req.flash('success_msg');
  res.locals.error_msg = req.flash('error_msg');
  res.locals.error = req.flash('error');
  next();
});

app.use('/users', require('./routes/users.js'));

const { ensureAuthenticated, forwardAuthenticated } = require('./config/auth');

// const https = require('https');


const API_KEY = "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";
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
  apiKey: API_KEY,
});
const openai = new OpenAIApi(configuration);







// Initialize PayPal SDK
paypal.configure({
  'mode': 'sandbox', // or 'live' for production
  'client_id': 'YOUR_CLIENT_ID',
  'client_secret': 'YOUR_CLIENT_SECRET'
});






async function sendEmail(to, subject, message) {
  // create transporter object using SMTP
  let transporter = nodemailer.createTransport({
    host: "mail.techmetic.co.ke",
    port: 465,
    secure: true,
    auth: {
      user: "benchomba@techmetic.co.ke",
      pass: "z-QYccw&*mTA"
    }
  });

  // define email options
  let mailOptions = {
    from: "benchomba@techmetic.co.ke",
    to: to,
    subject: subject,
    html: message
  };

  // send email
  await transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      console.log(error);
    } else {
      console.log("Email sent: " + info.response);
    }
  });
}








// Main Landing
app.get('/', (req,res)=>{
    res.render('landing')

})

app.get('/scrape2', (req,res)=>{

    // Find all emails whose address has '.co.ke'
const extensions = ['.com', '.co.ke', '.ca', '.com.ng', '.co.za', '.net', '.org'];

Email.find({address: /(.com|.co.ke|.ca|.com.ng|.co.za|.net|.org)/}, (err, emails) => {
  if (err) {
    console.log(err);
  } else {
    emails.forEach((email) => {
      for (let extension of extensions) {
        if (email.address.includes(extension)) {
          const index = email.address.indexOf(extension);
          const updatedAddress = email.address.slice(0, index + extension.length);
          email.address = updatedAddress;
          break;
        }
      }
      email.save((err) => {
        if (err) {
          console.log(err);
        }
      });
    });
  }
});


// Find all emails and group them by address
Email.aggregate([
  {
    $group: {
      _id: "$address",
      count: { $sum: 1 },
      emails: { $push: "$$ROOT" }
    }
  }
], (err, emailGroups) => {
  if (err) {
    console.log(err);
  } else {
    // Loop through the email groups and remove the extra ones
    emailGroups.forEach((emailGroup) => {
      if (emailGroup.count > 1) {
        // Remove all the emails except the first one
        for (let i = 1; i < emailGroup.count; i++) {
          Email.findByIdAndDelete(emailGroup.emails[i]._id, (err) => {
            if (err) {
              console.log(err);
            }
          });
        }
      }
    });
  }
});

// Find all emails whose address ends with '.png'
Email.find({address: /ENSafrica.com$/}, (err, emails) => {
if (err) {
console.log(err);
} else {
// Loop through the emails and delete them
emails.forEach((email) => {
email.remove((err) => {
if (err) {
console.log(err);
}
});
});
}
});

Email.find({address: /example|test|gmail@|mwakamuasu|gmail.com@/}, (err, emails) => {
  if (err) {
    console.log(err);
  } else {
    // Loop through the emails and delete them
    emails.forEach((email) => {
      email.remove((err) => {
        if (err) {
          console.log(err);
        }
      });
    });
  }
});

Email.find({address: /.*info/}, (err, emails) => {
  if (err) {
    console.log(err);
  } else {
    // Loop through the emails and update them
    emails.forEach((email) => {
      let updatedAddress = email.address.substring(email.address.indexOf("info"));
      email.update({$set: {address: updatedAddress}}, (err) => {
        if (err) {
          console.log(err);
        }
      });
    });
  }
});



// Find all emails whose address ends with '.png'
Email.find({address: /.png$/}, (err, emails) => {
if (err) {
console.log(err);
} else {
// Loop through the emails and delete them
emails.forEach((email) => {
email.remove((err) => {
if (err) {
console.log(err);
}
});
});
}
});

Email.find({}, (err, emails)=>{
    if (!err) {
        res.send(emails)
        console.log(emails.length)
    }
})


})


app.get('/scrape', (req,res)=>{
    
const request = require('request');
const cheerio = require('cheerio');

function truncateString(str) {
  const index = str.search(/(\.com|\.co\.ke|\.com\.ng|\.co\.za|\.org|\.ca|\.net)/);
  if (index === -1) return str;
  return str.slice(0, str.indexOf('/', index));
}


var webs = 1
console.log('hitttt')
// for(var i = 1; i < 3; i++){
var urls =[  'https://www.attorneys.co.za/resultsPage.asp?pagerecs=&Page=10&Name=&FirstName=&Surname=&sMode=A&RegionID=-1&AreaID=-1&SpecialtyID=-1&LanguageID=-1&post=yes']
 for(var i = 1; i < 9; i++){
const url = 'https://www.google.com/search?q=lawyer+in+nairobi&start='+i+'0';
if (url.length > 2) {
console.log(url + 'is on')

// request(url, (error, response, html) => {
//   if (!error && response.statusCode === 200) {
//     const $ = cheerio.load(html);

//     $('a').each((i, el) => {
//       const link = $(el).attr('href');
request(url, (error, response, html) => {
  if (!error && response.statusCode === 200) {
    const $ = cheerio.load(html);
    $('a').each((i, el) => {
      const link2 = $(el).attr('href');
      const link = link2.replace("/url?q=", "")
      if (link.length> 1) {

      console.log(link)
const scrapeEmails = (url) => {
  request(url, (error, response, html) => {
    if (!error && response.statusCode === 200) {
      const $ = cheerio.load(html);
      const emails = [];
      const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;

      // Find all email addresses on the pag
      const matches = $('body').text().match(emailRegex);
      if (matches) {
        matches.forEach((email)=>{
            console.log(email)


if (email != "asxvmprobertest@gmail.com") {
       Email.findOne({address:email }).then(existingEmail => {
        if (existingEmail) {
            console.log('Email exists')
        } else {
            Email.create({address: email, isEmailContacted: false}, (err, createdEmail)=>{
            if (err) {
                console.log(err)
            } else {
                console.log('email created - '+createdEmail)
            }
        })

        }
       } )        
  
}



        })
      }

    }
  });
};

// Start scraping from the initial URL
scrapeEmails(link);


}
  });
  }
});
}}
// }
})

// Customer Consultations
app.get('/agreement/:companyId', (req, res)=>{
    // Company.find({}, (err, companies)=>{
    //     if (!err) {
    //         res.send(companies)
    //     }
    // })
    var companyId = req.params.companyId
    Company.findOne({accountNumber:companyId}, function(err, company){
    if (err){
      console.log(err);
      res.send(err);

    }else{
        console.log(company)
  res.render('consultationPage', {company: company, companyId: companyId})
     }
  })
});





// Route for handling client form submissions
app.post("/generate-agreement/:companyId", async (req, res) => {

    let company;

  Company.findOne({ "_id": req.params.companyId }, function(err, result) {
    if (err) throw err;
    company = result;
    console.log(company);
    res.render('payClient', company);
   
  });



    //Check if the lawfirm has credit

    let count = 1;
    let agreement = '';
    while (count <= 5) {
        //Generate the agreement
        try {
            // Extract the form data
            const prompt = "Create a detailed agreement/document based on the following instructions The must sound as written by a topnotch attorney and sound very legal and foulproof. Make it very legal with subtitles and should sound like it is written by a top lawyer. Use the highest amount of words(more than 4000 words) possible for such so as to be most detailed. The instructions are: "+req.body.instructions;
            const response = await openai.createCompletion({
                model: "text-davinci-003",
                prompt: prompt,
                temperature: 1,
                max_tokens: 4000,
                top_p: 1.0,
                frequency_penalty: 0.0,
                presence_penalty: 0.0,
            });
    
            console.log(response.data.choices[0].text)
            // agreement = response.data.choices[0].text;

            Agreement.create({company: company._id, senderEmail: req.body.email, senderName: req.body.name, senderPhone: req.body.phone, senderCountry: req.body.senderCountry, basedOnLaws: req.body.country, generatedAgreement:response.data.choices[0].text, isPaidFor: false, isRead: false, isConfirmed: false}, (err, agreement)=>{
       if (err) {
        console.log(err)
       } else {
        console.log(agreement)

        if (agreement) {
        //Send a notification to the lawfirm of an incoming request
        sendEmail("bernardchombak@gmail.com", "AGREEMENT REQUEST FROM "+req.body.name, 
            `<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body {
        background-color: #1f2937;
        height: 70px;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0;
        padding: 0;
      }
      h1 {
        color: #ffcd78;
        text-align: center;
        width: 100%;
        padding: 0 10px;
        box-sizing: border-box;
      }
      p {
        width: 90%;
        margin: 10px auto;
        text-align: center;
        box-sizing: border-box;
        padding: 0 10px;
      }
      .button {
        background-color: #1f2937;
        color: #ffcd78;
        border-radius: 12px;
        padding: 10px 20px;
        text-align: center;
        display: inline-block;
        cursor: pointer;
        margin-top: 10px;
      }
    </style>
  </head>
  <body>
    <h1>Agreement Request on Agreegen Portal</h1>
    <p>
      Dear [Recipient],<br>
      I hope this email finds you well. I wanted to bring to your attention that you have received an agreement request on the Agreegen Portal.<br>
      To view the request, simply click the button below:<br>
      <a href="[Insert link to agreement request on Agreegen Portal]" class="button">View Request</a><br>
      Once you have reviewed the request, you will be able to take the necessary action. If you have any questions or concerns, please do not hesitate to reach out to me.<br>
      Thank you for your attention to this matter. I look forward to your response.
    </p>
    <p>
      Best regards,<br>
      [Your Name]
    </p>
  </body>
</html>

`)
        
        console.log(company + " work done")
    }
       }
   })
            break;
    
        } catch (err) {
            console.error(err);
            count++;
            if (count > 5) {
                res.status(500).send("An error occurred while generating the agreement.");
                break;
            }
        }
    }

    
});



// Route for handling ask differently form submissions
app.post("/generate-agreement/requestdifferently/:id", async (req, res) => {


	//Generate the agreement
    try {
        // Extract the form data
        const prompt = req.body.instructions;
        const response = await openai.createCompletion({
  model: "text-davinci-003",
  prompt: prompt,
  temperature: 1,
  max_tokens: 4000,
  top_p: 1.0,
  frequency_penalty: 0.0,
  presence_penalty: 0.0,
});

console.log(response.data.choices[0].text)
res.send(response.data.choices[0].text)

        // Add the generated response to the request's drafts
        console.log(response.choices[0].text);

        //redirect to the new page with new draft

    } catch (err) {
        console.error(err);
        res.status(500).send("An error occurred while generating the agreement.");
    }
});


// Route for handling edit submits form submissions
app.get("/generate-agreement/final/:id", async (req, res) => {
  // console.log(req.body);
  // try {
  //   const formData = req.body;
  //   const bgColor = "teal";
  //   const footerText = "This is awesome";

  //   // Create PDF options
  //   const pdfOptions = {
  //     format: "A4",
  //     orientation: "portrait",
  //     border: {
  //       top: "2cm",
  //       right: "1cm",
  //       bottom: "2cm",
  //       left: "1cm"
  //     },
  //     footer: {
  //       height: "2cm",
  //       contents: {
  //         default: `<div style="background-color: ${bgColor}; color: white; text-align: center;">${footerText}</div>`
  //       }
  //     },
  //     watermark: {
  //       image: "https://www.zamuraadvocates.co.ke/assets/images/logo.png",
  //       fit: [20, "auto"],
  //       position: "center",
  //       opacity: 0.4
  //     }
  //   };

  //   pdf
  //     .create(formData.html, pdfOptions)
  //     .toBuffer((err, buffer) => {
  //       if (err) {
  //         return res
  //           .status(500)
  //           .send("An error occurred while generating the PDF.");
  //       }
  //       const transporter = nodemailer.createTransport({
  //         host: "mail.techmetic.co.ke",
  //         port: 465,
  //         secure: true,
  //         auth: {
  //           user: "benchomba@techmetic.co.ke",
  //           pass: "z-QYccw&*mTA"
  //         }
  //       });

  //       const mailOptions = {
  //         from: "benchomba@techmetic.co.ke",
  //         to: "bernardchombak@gmail.com",
  //         cc: "salsykenya@gmail.com",
  //         subject: "Legal Agreement PDF",
  //         html: `
  //       <html>
  //           <head>
  //               <body style="
  //                   background-color: lightgrey;
  //                   width: 100%;
  //                   text-align: center;
  //                   font-family: Montserrat;
  //                 ">
  //                   <div style="
  //                     width: min(850px, 90%);
  //                     margin: 0 auto;
  //                   ">
  //                       <h1 style="color: teal">Agreement PDF</h1>
  //                       <p>Please find attached your agreement PDF.</p>
  //                   </div>
  //               </body>
  //           </head>
  //       </html>`,
  //         attachments: [
  //           {
  //             filename: "agreement.pdf",
  //             content: buffer
  //           }
  //         ]
  //       };

  //       transporter.sendMail(mailOptions, (error, info) => {
  //         if (error) {
  //           return res
  //             .status(500)
  //             .send("An error occurred while sending the PDF.");
  //         }
  //         res.status(200).send("PDF sent successfully.");
  //       });
  //     });
  // } catch (error) {
  // 	console.log(error)
  //   res.status(500).send("An error occurred.");
  // }

	const pdf = require('html-pdf');
const nodemailer = require('nodemailer');

const html = `
<html>
  <head>
    <style>
      .footer {
        background-color: teal;
        height: 2cm;
        text-align: center;
        color: white;
      }
      .watermark {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 30%;
        height: auto;
      }
    </style>
  </head>
  <body>
    <div class="watermark">
      <img src="https://www.zamuraadvocates.co.ke/assets/images/logo.png" />
    </div>
    <div class="footer">This is the footer</div>
  </body>
</html>
`;

pdf.create(html, { format: 'Letter' }).toBuffer((err, buffer) => {
  if (err) return console.error(err);

  const transporter = nodemailer.createTransport({
    // service: 'gmail',
    // auth: {
    //   user: 'youremail@gmail.com',
    //   pass: 'yourpassword'
    // }

     host: "mail.techmetic.co.ke",
    port: 465,
    secure: true, // true for 465, false for other ports
    auth: {
      user: "benchomba@techmetic.co.ke", // generated ethereal user
      pass: "z-QYccw&*mTA", // generated ethereal password
    },
    tls: {
                rejectUnauthorized: false
            }
  });
    

  const mailOptions = {
    from: 'benchomba@techmetic.co.ke',
    to: 'bernardchombak@gmail.com',
    subject: 'PDF Document',
    text: 'Attached is the PDF document',
    attachments: [
      {
        filename: 'document.pdf',
        content: buffer
      }
    ]
  };

  transporter.sendMail(mailOptions, (error, info) => {
    if (error) return console.error(error);
    console.log('Email sent: ' + info.response);
  });
});

});



//create smtp settings
app.post("/add-smtp-settings/:id", (req, res) => {

    const { host, port, secure, auth } = req.body;
    const transporter = nodemailer.createTransport({
        host,
        port,
        secure,
        auth
    });

    transporter.verify(function(error, success) {
        if (error) {
            res.send("Incorrect SMTP settings");
            //Save settings


        } else {
            res.send("SMTP settings are correct");
        }
    });
});


//Receive paypal payments
app.get('/pay-by-paypal', (req, res) => {
    // Render form for user to submit
    res.send(`
        <form method="post" action="/pay">
            <input type="submit" value="Pay $10 via PayPal">
        </form>
    `);
});

app.post('/pay-by-paypal', (req, res) => {
    // Create payment object
    const create_payment_json = {
        intent: 'sale',
        payer: {
            payment_method: 'paypal'
        },
        redirect_urls: {
            return_url: 'https://localhost.com/pay/success-paypal/request-id',
            cancel_url: 'https://localhost.com/pay/cancel-paypal/request-id'
        },
        transactions: [{
            item_list: {
                items: [{
                    name: 'Payment for service',
                    sku: 'item',
                    price: '10.00',
                    currency: 'USD',
                    quantity: 1
                }]
            },
            amount: {
                currency: 'USD',
                total: '10.00'
            },
            description: 'Payment for service'
        }]
    };

    // Create payment
    paypal.payment.create(create_payment_json, function (error, payment) {
        if (error) {
            console.log(error);
            throw error;
        } else {
            // Extract approval URL to redirect user
            for(let i = 0; i < payment.links.length; i++) {
                if (payment.links[i].rel === 'approval_url') {
                    res.redirect(payment.links[i].href);
                }
            }
        }
    });
});

app.get('/pay/success-paypal/:request-id', (req, res) => {
    // Retrieve payment ID and payer ID from query parameters
    const paymentId = req.query.paymentId;
    const payerId = { payer_id: req.query.PayerID };

    // Execute payment
    paypal.payment.execute(paymentId, payerId, function (error, payment) {
        if (error) {
            console.log(error);
            throw error;
        } else {
        	//Update the request as paid

            // Payment has been made
            console.log('A payment has been made');
            res.send('Payment Successful!');
        }
    });
});

app.get('/pay/cancel-paypal/:request-id', (req, res) => {
	//Notify the user that the payment was cancelled
    res.send('Payment Cancelled.');
});



//Process Flutterwave payments 
router.post('/pay-via-flutterwave', (req, res) => {
    // initialize flutterwave with your secret key
    flutterwave.initialize({
        secret_key: 'YOUR_SECRET_KEY'
    });

    // create a payload for the payment
    const payload = {
        amount: 1000, // $10 in kobo
        currency: "NGN",
        customer: {
            email: req.body.email,
            phone_number: req.body.phone
        },
        callback_url: "https://localhost.com/flutterwave/callback",
        success_url: "https://localhost.com/flutterwave/success",
        failure_url: "https://localhost.com/flutterwave/failed"
    }

    // create a payment
    flutterwave.payment.create(payload)
        .then(response => {
            // redirect user to the flutterwave payment page
            res.redirect(response.data.link)
        })
        .catch(error => {
            console.log(error)
            res.send('An error occured')
        })
})

router.get('/flutterwave/callback', (req, res) => {
    // validate the payment by verifying the transaction
    flutterwave.transaction.verify({
        transaction_reference: req.query.txref
    }).then(response => {
        console.log("A payment has been made")
    }).catch(error => {
        console.log("Payment validation failed")
    })
})

router.get('/flutterwave/success', (req, res) => {
    res.send("Payment successful")
})

router.get('/flutterwave/failed', (req, res) => {
    res.send("Payment failed or cancelled")
})




//Pesapal Payment Processing

app.get('/pesapal-pay', (req, res) => {
    res.send(`
        <form action="/pay" method="post">
            <input type="submit" value="Pay $10 via Pesapal">
        </form>
    `);
});

app.post('/pay-pesapal', (req, res) => {
    // Dummy credentials
    const pesapalConsumerKey = 'your_consumer_key';
    const pesapalConsumerSecret = 'your_consumer_secret';

    // Create a new Pesapal payment
    const payment = new pesapal.Pesapal(pesapalConsumerKey, pesapalConsumerSecret);
    payment.pay('10.00', 'USD', 'Payment for service', 'your-merchant-email@example.com', 'https://localhost.com/pesapal-success/uniquecode', 'https://localhost.com/pesapal-canceled/uniquecode');

    res.redirect(payment.url());
});

app.get('/pesapal-success/:id', (req, res) => {
    // Validate payment and console log result
    const payment = new pesapal.Pesapal(pesapalConsumerKey, pesapalConsumerSecret);
    if (payment.validate()) {
        console.log('A payment has been made');
        res.send('Payment Successful');
    } else {
        console.log('Payment failed');
        res.send('Payment Failed');
    }
});

app.get('/pesapal-canceled/:id', (req, res) => {
    console.log('Payment canceled');
    res.send('Payment Canceled');
});







const port = 3000;
app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
});




