// ATTENTION! If you customize this file, please create a backup of this file.
// This file will get overwritten on every update.

const arrocy = require('./lib');
const path = require('path');
const { v4 } = require('uuid');

// forwardMessage (params: token, msgId)
arrocy.router.post('/forwardMessage', (req, res) => {
  arrocy.dbQuery(`SELECT * FROM devices WHERE token = '${req.body.token}'`).then((devices) => {
    if (!devices[0]) {
      res.status(500).send({ success: false, message: 'Invalid token' });
    }
    arrocy.dbQuery(`SELECT * FROM messages WHERE key_id = '${req.body.msgId}'`).then(async (result) => {
      const msg = JSON.parse(result[0].message);
      if (!msg) return res.status(500).send({ success: false, message: 'msg not found' });
      console.log(msg);
      const sock = await client(device, 'getSock', req.body, res);
      const response = await sock.sendMessage('919425008429@s.whatsapp.net', { forward: msg });
      res.status(200).send({ success: true, message: response });
    });
  });
});

// params: token
// api endpoint: https://api.mydomain.com/walogout?token=device-token
arrocy.router.get('/walogout', (req, res) => {
  arrocy.dbQuery(`SELECT * FROM devices WHERE token = '${req.query.token}'`, (result) => {
    if (!result[0]) res.status(500).send({ success: false, message: 'Invalid token.' });
    const config = { sender: result[0].sender, task: 'logout' };
    arrocy.create(config);
    res.status(200).send({ success: true, message: result[0].sender + ' logged out.' });
  });
});

// example: delete Autoreply PAUSED files older than 30 days
// api endpoint: https://api.mydomain.com/del-autoreply-paused?token=super-secret-password
// add cronjob: curl 'https://api.mydomain.com/del-autoreply-paused?token=super-secret-password' >> /dev/null 2>&1
arrocy.router.get('/del-autoreply-paused', (req, res) => {
  if (req.query.token !== 'super-secret-password') return res.status(500).send({ success: false, message: 'Invalid token!' });
  const dirPath = './sessions';
  const arFolders = arrocy.fs.readdirSync(dirPath).filter((file) => arrocy.fs.statSync(path.join(dirPath, file)).isDirectory() && file.startsWith('ar_'));
  let count = 0;
  for (const folder of arFolders) {
    const folderPath = path.join(dirPath, folder);
    const time = new Date().getTime() - 30 * 24 * 60 * 60 * 1000; // days * hours * minutes * seconds * milliseconds
    const files = arrocy.fs
      .readdirSync(folderPath)
      .map((file) => path.join(folderPath, file))
      .filter((file) => {
        const fileStats = arrocy.fs.statSync(file);
        return fileStats.birthtime.getTime() < time;
      });

    for (const file of files) {
      arrocy.fs.unlinkSync(file);
      console.log(`Deleted: ${file}`);
      count++;
    }
  }
  console.log(`\nTotal files deleted: ${count}`);
  res.status(200).send({
    success: true,
    message: `${count} Autoreply paused files successfully deleted.`,
  });
});

// example: delete media files older than 30 days
// api endpoint: https://api.mydomain.com/del-medias?token=super-secret-password
// add cronjob: curl 'https://api.mydomain.com/del-medias?token=super-secret-password' >> /dev/null 2>&1
arrocy.router.get('/del-medias', (req, res) => {
  if (req.query.token !== 'super-secret-password') return res.status(500).send({ success: false, message: 'Invalid token!' });
  const dirPath = './sessions/medias';
  const mediaFolders = arrocy.fs.readdirSync(dirPath).filter((file) => arrocy.fs.statSync(path.join(dirPath, file)).isDirectory() && file.startsWith('me_'));
  let count = 0;
  for (const folder of mediaFolders) {
    const folderPath = path.join(dirPath, folder);
    const time = new Date().getTime() - 30 * 24 * 60 * 60 * 1000; // days * hours * minutes * seconds * milliseconds
    const files = arrocy.fs
      .readdirSync(folderPath)
      .map((file) => path.join(folderPath, file))
      .filter((file) => {
        const fileStats = arrocy.fs.statSync(file);
        return fileStats.birthtime.getTime() < time;
      });

    for (const file of files) {
      arrocy.fs.unlinkSync(file);
      console.log(`Deleted: ${file}`);
      count++;
    }
  }
  console.log(`\nTotal files deleted: ${count}`);
  res.status(200).send({
    success: true,
    message: `${count} Session files successfully deleted.`,
  });
});

// example: delete sessions files except creds.json
// api endpoint: https://api.mydomain.com/del-sessions?token=super-secret-password
// add cronjob: curl 'https://api.mydomain.com/del-sessions?token=super-secret-password' >> /dev/null 2>&1
arrocy.router.get('/del-sessions', async (req, res) => {
  if (req.query.token !== 'super-secret-password') return res.status(500).send({ success: false, message: 'Invalid token!' });
  const dirPath = './sessions';
  const waFolders = arrocy.fs.readdirSync(dirPath).filter((file) => arrocy.fs.statSync(path.join(dirPath, file)).isDirectory() && file.startsWith('wa_'));
  let count = 0;
  for (const folder of waFolders) {
    const folderPath = path.join(dirPath, folder);
    const files = await arrocy.fs
      .readdirSync(folderPath)
      .map((file) => path.join(folderPath, file))
      .filter((file) => file !== path.join(folderPath, 'creds.json'));

    for (const file of files) {
      arrocy.fs.unlinkSync(file);
      console.log(`Deleted: ${file}`);
      count++;
    }
  }
  console.log(`\nTotal files deleted: ${count}`);
  res.status(200).send({
    success: true,
    message: `${count} Session files successfully deleted.`,
  });
});

// example: read a file, then response if requested
// api endpoint: https://api.mydomain.com/filecontents
const filecontents = arrocy.fs.readFileSync('package.json');
arrocy.router.get('/filecontents', (req, res) => {
  res.status(200).send({ success: true, message: Buffer.from(filecontents).toString('utf-8') });
});

// param: sender or token
// api endpoint: https://api.mydomain.com/device-status?sender=6281212341234
arrocy.router.get('/device-status', (req, res) => {
  let colName, colValue;
  if (req.query?.token) {
    colName = 'token';
    colValue = req.query.token;
  } else if (req.query?.sender) {
    colName = 'sender';
    colValue = req.query.sender;
  }
  if (colName === undefined) return res.status(500).send({ success: false, sender: 'NO PARAM', status: 'NO PARAM', message: `param sender or token required.` });
  arrocy.dbQuery(`SELECT * FROM devices WHERE ${colName} = '${colValue}'`, (devices) => {
    if (!devices[0]) res.status(200).send({ success: false, sender: 'DEVICE NOT FOUND', status: 'DEVICE NOT FOUND', message: `Device is not in database.` });
    const sender = devices[0].sender;
    const status = devices[0].status;
    res.status(200).send({ success: true, sender: sender, status: status, message: `Device ${sender} status is ${status}.` });
  });
});

// example: read database table packages, then response if requested
// api endpoint: https://api.mydomain.com/packages
arrocy.dbQuery('SELECT * FROM packages', (result) => {
  arrocy.router.get('/packages', (req, res) => {
    res.status(200).send({ success: true, message: result });
  });
});

// add device (params: user_id, password (hashed password from database), sender)
// api endpoint: https://api.mydomain.com/adddevice?user_id=1&password=$2y$10$ya6h2H/0HGJXTXHn/tkd.O14h6fHrjc4pVF7ipWdQ5FuIaz/dtrkK&sender=621234512345
arrocy.router.get('/adddevice', (req, res) => {
  const user_id = req.query?.user_id || 1;
  const password = req.query?.password;
  const openai =
    '{"apikey":"","contain":"test,","model":"gpt-3.5-turbo","image_contain":"Generate image","image_model":"dall-e-3","max_tokens":200,"save_chats":0,"persona":"Your name is test. You are a smart, polite, and gentle assistant"}';
  const sender = req.query?.sender;
  const token = v4();
  arrocy.dbQuery(`SELECT * FROM users WHERE id = '${user_id}' AND password = '${password}'`, (user) => {
    if (user.length > 0) {
      arrocy.dbQuery(`SELECT * FROM devices WHERE sender = '${sender}'`, (result) => {
        if (result.length === 0) {
          arrocy.dbQuery(`INSERT INTO devices (user_id, name, sender, token, openai) VALUES (${user_id}, '${sender}', '${sender}', '${token}', '${openai}')`, () => {});
          res.status(200).send({ success: true, message: `Device ${sender} is created successfully.`, token: token });
        } else {
          res.status(500).send({ success: false, message: `Device ${sender} already in database. Add device failed.` });
        }
      });
    } else {
      res.status(500).send({ success: false, message: 'Invalid user_id or password' });
    }
  });
});

// delete device (params: sender, token)
// api endpoint: https://api.mydomain.com/deldevice?sender=621234512345&token=rjc4pVF7ipWdQ5FuIaz
arrocy.router.get('/deldevice', (req, res) => {
  const sender = req.query?.sender;
  const token = req.query?.token;
  arrocy.dbQuery(`DELETE FROM devices WHERE sender = '${sender}' AND token = '${token}'`, () => {});
  if (arrocy.fs.existsSync(`./sessions/wa_${sender}`)) fs.rmSync(`./sessions/wa_${sender}`, { recursive: true });
});

arrocy.router.get('/latest-waweb', async (req, res) => {
  const response = await fetch('https://web.whatsapp.com/check-update?version=2.2210.9&platform=web');
  if (response.status === 200) {
    let data = await response.json();
    let version = data.currentVersion.split('.');
    console.log(
      'Latest Whatsapp Web version:',
      version.map((n) => n)
    );
    return res.status(200).send({ success: true, message: version.map((n) => n) });
  } else {
    res.status(500).send({ success: false, message: 'Fetch latest Whatsapp Web version failed' });
  }
});

arrocy.router.get('/latest-waweb', async (req, res) => {
  const response = await fetch('https://web.whatsapp.com/check-update?version=2.2210.9&platform=web');
  if (response.status === 200) {
    let data = await response.json();
    let version = data.currentVersion.split('.');
    console.log(
      'Latest Whatsapp Web version:',
      version.map((n) => n)
    );
    return res.status(200).send({ success: true, message: version.map((n) => n) });
  } else {
    res.status(500).send({ success: false, message: 'Fetch latest Whatsapp Web version failed' });
  }
});

// api endpoint: https://api.mydomain.com/get-session/am_97337780873/97339116526.txt
arrocy.router.get('/get-session/:sender/:receiver', async (req, res) => {
  const sender = req.params.sender;
  const receiver = req.params.receiver;
  try {
    const session = arrocy.fs.readFileSync(`./sessions/${sender}/${receiver}`, 'utf8');
    res.status(200).send({ success: true, message: typeof session === 'string' ? session : typeof session === 'object' ? JSON.parse(session) : '' });
  } catch (error) {
    res.status(500).send({ success: false, message: 'Session not found' });
  }
});

// example: basic text response if requested
// api endpoint: https://api.mydomain.com/example
arrocy.router.get('/example', (req, res) => {
  res.status(200).send({ success: true, message: 'this is an example of API response' });
});

arrocy.forever(); // keep alive algorithm. DO NOT REMOVE!
