import qrCode from "qrcode-terminal";
import { Client, LocalAuth } from "whatsapp-web.js";
import { getIO } from "./socket";
import Whatsapp from "../models/Whatsapp";
import AppError from "../errors/AppError";
import { logger } from "../utils/logger";
import { handleMessage } from "../services/WbotServices/wbotMessageListener";
const fs = require('fs')

import { copyFolder } from "../helpers/CopyFolder";
import path from "path";
import { number } from "yup";
import { removeDir } from "../helpers/DeleteDirectory";

interface Session extends Client {
  id?: number;
}

const sessions: Session[] = [];

let backupSession: any[] = []

// import { insertOrUpeateWhatsCache } from "../helpers/WhatsCache";
import { json } from "sequelize/types";
import { restartWhatsSession } from "../helpers/RestartWhatsSession";
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";

let miliseconds = [1000, 2000, 3000]

const syncUnreadMessages = async (wbot: Session) => {
  const chats = await wbot.getChats();

  /* eslint-disable no-restricted-syntax */
  /* eslint-disable no-await-in-loop */
  for (const chat of chats) {

    if (chat.unreadCount > 0) {

      const unreadMessages = await chat.fetchMessages({
        limit: chat.unreadCount
      });

      for (const msg of unreadMessages) {

        // console.log('--BACKEND MSG: ', msg)

        await handleMessage(msg, wbot);
      }

      await chat.sendSeen();
    }

  }
};

export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean = false): Promise<Session> => {
  return new Promise((resolve, reject) => {
    try {


      const io = getIO();
      const sessionName = whatsapp.name;
      let sessionCfg;

      if (whatsapp && whatsapp.session) {
        sessionCfg = JSON.parse(whatsapp.session);
      }


      //NOVA OPÇÃO MD
      // const wbot: Session = new Client({
      //   session: sessionCfg, authStrategy: new LocalAuth({ clientId: 'bd_' + whatsapp.id }),
      //   puppeteer: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: process.env.CHROME_BIN || undefined },
      // });

      // usando instancia do chrome
      // const wbot: Session = new Client({
      //   session: sessionCfg, authStrategy: new LocalAuth({ clientId: 'bd_' + whatsapp.id }),
      //   // puppeteer: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: process.env.CHROME_BIN || undefined },
      //   puppeteer: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: process.env.CHROME_BIN ||  '/usr/bin/google-chrome-stable'  },

      // });

      const args: String = process.env.CHROME_ARGS || "";

      const wbot: Session = new Client({
        session: sessionCfg,
        authStrategy: new LocalAuth({ clientId: 'bd_' + whatsapp.id }),
        puppeteer: {
          executablePath: process.env.CHROME_BIN || undefined,
          // @ts-ignore
          browserWSEndpoint: process.env.CHROME_WS || undefined,
          args: args.split(' ')
        }
      });


      wbot.initialize();

      wbot.on("qr", async qr => {


        if (!backupSession.includes(whatsapp.id)) {
          backupSession.push(whatsapp.id)
        }

        console.log('************** QRCODE whatsapp.id: ', whatsapp.id, '  | backupSession: ', backupSession)

        logger.info("Session:", sessionName);
        qrCode.generate(qr, { small: true });
        await whatsapp.update({ qrcode: qr, status: "qrcode", retries: 0 });
        // await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { qrcode: qr, status: "qrcode", retries: 0 })

        const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
        if (sessionIndex === -1) {
          wbot.id = whatsapp.id;
          sessions.push(wbot);
        }

        io.emit("whatsappSession", {
          action: "update",
          session: whatsapp
        });
      });

      wbot.on("authenticated", async session => {
        logger.info(`Session: ${sessionName} AUTHENTICATED`);

      });

      wbot.on("auth_failure", async msg => {
        console.error(
          `Session: ${sessionName} AUTHENTICATION FAILURE! Reason: ${msg}`
        );

        if (whatsapp.retries > 1) {
          await whatsapp.update({ session: "", retries: 0 });
          // await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { session: "", retries: 0 })
        }

        const retry = whatsapp.retries;
        await whatsapp.update({
          status: "DISCONNECTED",
          retries: retry + 1
        });
        // await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, {
        //   status: "DISCONNECTED",
        //   retries: retry + 1
        // })

        io.emit("whatsappSession", {
          action: "update",
          session: whatsapp
        });

        reject(new Error("Error starting whatsapp session."));
      });

      wbot.on("ready", async () => {
        logger.info(`Session: ${sessionName} READY`);

        if (whatsapp.name.includes(wbot.info["wid"]["user"])) {
          console.log('-----------------> THIS IS THE RIGHT NUMBER')
        }
        else {
          console.log('-----------------> THIS IS THE WRONG NUMBER')
          let read_number = wbot.info["wid"]["user"]

          await wbot.logout()

          io.emit("whatsappSession", {
            action: "error",
            msg: `Numero lido: ${read_number} \nEssa sessão de whatsapp foi desconectada porque o numero que esta descrito no nome dessa sessão não corresponde ao numero lido!`
          });

          return
        }


        await whatsapp.update({
          status: "CONNECTED",
          qrcode: "",
          retries: 0,
          number: wbot.info["wid"]["user"]
        });
        // await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, whatsapp)

        io.emit("whatsappSession", {
          action: "update",
          session: whatsapp
        });

        const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
        if (sessionIndex === -1) {
          console.log('WBOT ADD ID: ', whatsapp.id)
          wbot.id = whatsapp.id;
          sessions.push(wbot);
        }

        wbot.sendPresenceAvailable();
        await syncUnreadMessages(wbot);

        resolve(wbot);




        console.log(`>>>>>>>>>>>>>>>>>>>>>>>>> BACKUP SESSION whatsapp.id ${whatsapp.id} | backupSession: ${backupSession}`)

        const whatsIndex = backupSession.findIndex((id: number) => id === +whatsapp.id);

        console.log('               whatsIndex: ', whatsIndex)

        if (whatsIndex !== -1 || backupSessionRestore) {

          if (whatsIndex !== -1) {
            backupSession.splice(whatsIndex, 1);
          }


          setTimeout(async () => {

            const sourcePath = path.join(__dirname, `../../.wwebjs_auth/`, `session-bd_${whatsapp.id}`)
            const destPath = path.join(__dirname, `../../.wwebjs_auth/sessions`, `session-bd_${whatsapp.id}`)

            if (fs.existsSync(path.join(__dirname, `../../.wwebjs_auth/sessions`))) {

              await removeDir(destPath)

              // copy the good session for backup dir
              copyFolder(sourcePath, destPath)
            }
            else {
              console.log('Directory not found to copy: ', destPath)
            }

            console.log(` COPIOU backup whatsapp.id ---------------------------------->${whatsapp.id}`)


          }, 90000);

          console.log('                                PASSOU NO TIMEOUT whatsapp.id: ', whatsapp.id)


        }
      });
    } catch (err) {
      logger.error(`${err}`);
    }
  });
};

export const getWbot = async (whatsappId: number | string): Promise<any> => {

  console.log('getWbot whatsappId: ', whatsappId)

  let whatsapp = await Whatsapp.findByPk(whatsappId, {
    attributes: ["url"]
  })

  if (whatsapp && whatsapp.status != 'CONNECTED') {

    let listWhatsapp: any = null

    // listWhatsapp = await searchWhatsappCache(`${ticket.whatsappId}`, 'CONNECTED')

    if (!listWhatsapp) {

      listWhatsapp = await ListWhatsAppsNumber(whatsappId, 'CONNECTED')

    }

    if (listWhatsapp.whatsapps && listWhatsapp.whatsapps.length > 0) {

      console.log('----------> getWbot has changed the whatsappId: ', listWhatsapp.whatsapps[0].id)

      whatsapp = await Whatsapp.findByPk(listWhatsapp.whatsapps[0].id, {
        attributes: ["url"]
      })

    }

  }

  if (whatsapp && (whatsapp.url && whatsapp.url.length > 0)) {

    return whatsapp.url

  }

  return null


  // const sessionIndex = sessions.findIndex(s => s.id === whatsappId);

  // if (sessionIndex === -1) {
  //   throw new AppError("ERR_WAPP_NOT_INITIALIZED");
  // }

  // return sessions[sessionIndex];
};

export const removeWbot = (whatsappId: number): void => {
  try {
    const sessionIndex = sessions.findIndex(s => s.id === whatsappId);
    if (sessionIndex !== -1) {
      console.log('WBOT REMOVED ID: ', whatsappId)
      sessions[sessionIndex].destroy();
      sessions.splice(sessionIndex, 1);
    }
  } catch (err) {
    logger.error(`${err}`);
  }
};
