import axios from "axios";
import express, { json, query } from "express";
import Queue from "bull";
import Bottleneck from "bottleneck";

const app = express();
app.use(json());

const requestQueue = new Queue("request-queue");

const limiter = new Bottleneck({
  maxConcurrent: 2, // Number of concurrent requests
  minTime: 1, // Minimum time between requests (in milliseconds)
});

async function sendRequest(data) {
  const botToken = data.botToken;
  const chatId = data.chatId;
  const text = data.text;
  try {
    const response = await axios.post(
      `https://api.telegram.org/bot${botToken}/sendMessage`,
      {
        chat_id: chatId,
        text: text,
      }
    );
  } catch (error) {
    console.error(
      "Error:",
      error.response ? error.response.data : error.message
    );
  }
}

requestQueue.process(async (job) => {
  try {
    const result = await limiter.schedule(() => sendRequest(job.data));
    return result;
  } catch (error) {
    throw new Error(`Request failed: ${error.message}`);
  }
});

// Handle job completion
requestQueue.on("completed", (job) => {
  console.log(`Job ${job.id} completed successfully.`);
});

// Handle job failure and retry
requestQueue.on("failed", (job, error) => {
  console.log(`Job ${job.id} failed with error: ${error.message}`);
  if (job.attemptsMade < 3) {
    // Retry up to 3 times
    job.retry();
  } else {
    console.error(
      `Job ${job.id} moved to dead-letter queue after ${job.attemptsMade} attempts`
    );
  }
});

app.get("/bot:token/*", async (req, res) => {
  const url = req.url
  const botTokenEndIndex = url.indexOf("/", 1)
  const botToken = url.substring(4, botTokenEndIndex)
  
  const queryParams = req.query;
  
  const data = {
    botToken: botToken,
    chatId: queryParams.chat_id,
    text: queryParams.text,
  };
  try {
    const job = await requestQueue.add(data, {
      attempts: 3,
      backoff: 5000,
    });
    res.status(202).send({ jobId: job.id });
  } catch (error) {
    res.status(500).send({ error: error.message });
  }
});

// Endpoint to add a request to the queue
app.post("/sendMessage", async (req, res) => {
  try {
    const job = await requestQueue.add(req.body, {
      attempts: 3,
      backoff: 5000,
    });
    res.status(202).send({ jobId: job.id });
  } catch (error) {
    res.status(500).send({ error: error.message });
  }
});

// Start the server
app.listen(3000, () => {
  console.log("Microservice listening on port 3000");
});
