const {queryDb} = require("./db");
const logger = require('./logger');
const userAg = require('useragent');
const moment = require('moment');
// const { verifyRecaptcha } = require('./recaptcha');
const getURLParameters = require('./urlParameters');

function isWebview(userAgentString) {
  const agent = userAg.parse(userAgentString);

  const isWebview = (
    agent.family === 'Android WebView' ||
    agent.family === 'WKWebView' ||
    agent.family === 'UIWebView'
  );

  return isWebview;
}

async function isBotTraffic(visitorIp, url) {
  const checkUrl = url.split('=')[0];
  console.log('url: ', url);

  let urlIncludesGClId = false;
  let blockReason = '';
  let data = {
    initialUrl: url,
    isBot: true,
    blockReason: '',
  };

  if (checkUrl.includes('?gclid')) {
    urlIncludesGClId = true;
    console.log('The checkUrl CONTAINS "?gclid"');
  } else {
    console.log('The checkUrl does NOT contain "?gclid"');
  }

  try { //checking user agent
    const today = moment().format('YYYY-MM-DD');
    const searchQuery = `SELECT * FROM Logs WHERE ip = '${visitorIp}' AND DATE(date) = '${today}' AND url LIKE '%${checkUrl}%'`;
    const rows = await queryDb(searchQuery);

    if(rows.length === 0){
        data.blockReason = 'Not blocked, no logs found';
        data.blockIP = false;
    } else if(rows.length >= 1 && urlIncludesGClId){
        data.blockReason = 'Accessed today 2+ times the same page with gclid';
        console.log(`IP found : ${visitorIp}`);
        data.blockIP = true;
    } else if(rows.length >= 3){
        data.blockReason = 'Accessed today 4+ times the same page without gclid';
        console.log(`IP found : ${visitorIp}`);
        data.blockIP = true;
    } else {
        data.blockReason = 'Not blocked, no conditions met';
        data.blockIP = false;
    }
  } catch (error) {
    logger.error('Error selecting data from db:', error);
    console.error('Error selecting data from db:', error);
  }

  try { //checking if multiple entries from the same ip
    const today = moment().format('YYYY-MM-DD');
    const searchQuery = `SELECT * FROM Logs WHERE ip = '${visitorIp}' AND DATE(date) = '${today}' AND url LIKE '%${checkUrl}%'`;
    const rows = await queryDb(searchQuery);

    if(rows.length === 0){
        data.blockReason = 'Not blocked, no logs found';
        data.blockIP = false;
    } else if(rows.length >= 1 && urlIncludesGClId){
        data.blockReason = 'Accessed today 2+ times the same page with gclid';
        console.log(`IP found : ${visitorIp}`);
        data.blockIP = true;
    // } else if(rows.length >= 3){
    //     data.blockReason = 'Accessed today 4+ times the same page without gclid';
    //     console.log(`IP found : ${visitorIp}`);
    //     data.blockIP = true;
    } else {
        data.blockReason = 'Not blocked, no conditions met';
        data.blockIP = false;
    }
  } catch (error) {
    logger.error('Error selecting data from db:', error);
    console.error('Error selecting data from db:', error);
  }


  return data;
}

async function insertBlockedIP(visitorIp, blockReason) {
  try {
    const insertQuery = `INSERT INTO BlockedIPs (ip, reason) VALUES ('${visitorIp}', '${blockReason}');`;
    await queryDb(insertQuery);
    console.log(`Inserted in BlockedIPs: ${visitorIp}`);
  } catch (error) {
    console.error('Error inserting IP into BlockedIPs table:', error);
  }
}

module.exports = async function dbLogger(req, isVpn) {
  // const token = req.body.recaptchaToken; // Replace with the token received from the client
  // const { success, score } = await verifyRecaptcha(token);
  // let reCScore = null;


  // if (success && score >= 0.5) {
  //   // Proceed with the protected action or API call
  //   console.log('Recaptcha Success score: ', score);
  //   reCScore = score;
  // } else if (success) {
  //   // Handle the failed verification
  //   console.log('Recaptcha low score: ', score)
  //   reCScore = score;
  // } else {
  //   // Handle the failed verification
  //   console.log('Recaptcha Fail')
  //   // res.status(403).send('reCAPTCHA verification failed');
  //   reCScore = -1;
  // }

  const ipAddress = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  const visitorIp = ipAddress.split(',')[0].trim();
  const userAgentSource = req.useragent.source;
  const userAgentString = req.headers['user-agent'];
  const isWebViewAgent = isWebview(userAgentString);
  // const isVPN = /vpn|proxy|tor/i.test(userAgentSource);
  // const isWebViewAgent = req.useragent.isWebView;
  const isVPN = req.isVPN;
  // logger.info('ip adress: ', ipAddress);

  if (req.url.includes('/img/') || req.url.includes('/favicon.ico')) {
    // console.log('req.url contains "/img/"');
    return;
  } 

  const isBotData = await isBotTraffic(visitorIp, req.url);
  console.log(isBotData.isBot);
  console.log('blockReason:', isBotData.blockReason);

  let isBlockedIp = 0;
  let ipBlockedNow = 0;

    try {
      const dontDuplicateQuery = `SELECT * FROM BlockedIPs WHERE ip = '${visitorIp}';`;
      const isIpInBlocked = await queryDb(dontDuplicateQuery);

      if(isIpInBlocked.length === 0){
        console.log(`Ip is not in BlockedIPs: ${visitorIp}; blockIP is: ${isBotData.blockIP}`);

        if (req.useragent.isTablet && req.useragent.os === 'unknown' && req.useragent.platform === 'Android') {
          insertBlockedIP(visitorIp, 'Tablet & OS = unknown & Platform = Android');
          ipBlockedNow = 1;
        } else if (req.useragent.browser === 'Firefox' && req.useragent.os === 'unknown' && req.useragent.platform === 'Android') {
          insertBlockedIP(visitorIp, 'Browser = Firefox & OS = unknown & Platform = Android');
          ipBlockedNow = 1;
        } else if (req.useragent.browser === 'Chrome' && req.useragent.os === 'Linux' && req.useragent.platform === 'Android') {
          insertBlockedIP(visitorIp, 'Browser = Chrome & OS = Linux & Platform = Android');
          ipBlockedNow = 1;
        }
        
        if (isBotData.blockIP) {
          insertBlockedIP(visitorIp, isBotData.blockReason);
          ipBlockedNow = 1;
        }

        if(ipBlockedNow === 1){
          console.log(`Blocked IP successful: ${visitorIp}`);
        }

      } else {
        console.log(`Ip is in BlockedIPs: ${visitorIp}`);
        isBlockedIp = 1;
      }
    } catch (error) {
      // logger.error('Error querying data:', error);
      console.error('Error querying data:', error);
    }

    const parameters = await getURLParameters('https://24hrslocksmith.co.uk' + req.url);
    campaignParam = parameters.find(param => param.name === 'campaign')?.value;
    adGroupParam = parameters.find(param => param.name === 'adgroup')?.value;
    campaignIdParam = parameters.find(param => param.name === 'campaignid')?.value;
    adGroupIdParam = parameters.find(param => param.name === 'adgroupid')?.value;
    keywordParam = parameters.find(param => param.name === 'keyword')?.value;
    deviceParam = parameters.find(param => param.name === 'device')?.value;
    adPositionParam = parameters.find(param => param.name === 'adposition')?.value;

  try {
    console.log('url: ', isBotData.initialUrl);
    const q = `INSERT INTO Logs (ip, url, campaign, adgroup, campaignid, adgroupid, keyword, device, adposition, isBlockedIp, blockedNow, user_agent, user_agent_source, is_webview, is_vpn, browser, version, os, platform, geoIp, isYaBrowser, isAuthoritative, isMobile, isMobileNative, isTablet, isiPad, isiPod, isiPhone, isiPhoneNative, isAndroid, isAndroidNative, isBlackberry, isOpera, isIE, isEdge, isIECompatibilityMode, isSafari, isFirefox, isWebkit, isChrome, isKonqueror, isOmniWeb, isSeaMonkey, isFlock, isAmaya, isPhantomJS, isEpiphany, isDesktop, isWindows, isLinux, isLinux64, isMac, isChromeOS, isBada, isSamsung, isRaspberry, is_bot, isCurl, isAndroidTablet, isWinJs, isKindleFire, isSilk, isCaptive, isSmartTV, isUC, isFacebook, isAlamoFire, isElectron, silkAccelerated, isWechat) VALUES ('${visitorIp}','${isBotData.initialUrl}','${campaignParam}','${adGroupParam}','${campaignIdParam}','${adGroupIdParam}','${keywordParam}','${deviceParam}','${adPositionParam}','${isBlockedIp}','${ipBlockedNow}','${JSON.stringify(req.useragent)}', '${userAgentSource}', ${isWebViewAgent}, ${isVPN}, '${req.useragent.browser}', '${req.useragent.version}', '${req.useragent.os}', '${req.useragent.platform}', '${JSON.stringify(req.useragent.geoIp)}', ${req.useragent.isYaBrowser}, ${req.useragent.isAuthoritative}, ${req.useragent.isMobile}, ${req.useragent.isMobileNative}, ${req.useragent.isTablet}, ${req.useragent.isiPad}, ${req.useragent.isiPod}, ${req.useragent.isiPhone}, ${req.useragent.isiPhoneNative}, ${req.useragent.isAndroid}, ${req.useragent.isAndroidNative}, ${req.useragent.isBlackberry}, ${req.useragent.isOpera}, ${req.useragent.isIE}, ${req.useragent.isEdge}, ${req.useragent.isIECompatibilityMode}, ${req.useragent.isSafari}, ${req.useragent.isFirefox}, ${req.useragent.isWebkit}, ${req.useragent.isChrome}, ${req.useragent.isKonqueror}, ${req.useragent.isOmniWeb}, ${req.useragent.isSeaMonkey}, ${req.useragent.isFlock}, ${req.useragent.isAmaya}, ${req.useragent.isPhantomJS}, ${req.useragent.isEpiphany}, ${req.useragent.isDesktop}, ${req.useragent.isWindows}, ${req.useragent.isLinux}, ${req.useragent.isLinux64}, ${req.useragent.isMac}, ${req.useragent.isChromeOS}, ${req.useragent.isBada}, ${req.useragent.isSamsung}, ${req.useragent.isRaspberry}, ${req.useragent.isBot}, ${req.useragent.isCurl}, ${req.useragent.isAndroidTablet}, ${req.useragent.isWinJs}, ${req.useragent.isKindleFire}, ${req.useragent.isSilk}, ${req.useragent.isCaptive}, ${req.useragent.isSmartTV}, ${req.useragent.isUC}, ${req.useragent.isFacebook}, ${req.useragent.isAlamoFire}, ${req.useragent.isElectron}, ${req.useragent.silkAccelerated}, ${req.useragent.isWechat});`;
    const result = await queryDb(q);
    logger.info('Inserted ip in Logss');
  } catch (error) {
    logger.error('Error inserting data', error);
    console.error('Error inserting data:', error);
  }
};