/**
 * Auto Bypass Cloudflare Bot untuk app.weavy.ai
 * 
 * Skrip ini secara otomatis:
 * 1. Membuka browser menggunakan puppeteer-real-browser
 * 2. Menavigasi ke halaman target
 * 3. Menunggu Cloudflare Turnstile diselesaikan secara otomatis
 * 4. Mengekstrak cookie cf_clearance, headers, dan token
 * 5. Menyimpan hasilnya ke file JSON untuk digunakan skrip lain
 * 6. Secara berkala me-refresh session sebelum kedaluwarsa
 */

const { connect } = require("puppeteer-real-browser");
const fs = require("fs");
const path = require("path");

// === KONFIGURASI ===
const CONFIG = {
  targetUrl: "https://app.weavy.ai/signin",
  outputFile: path.join(__dirname, "session.json"),
  refreshIntervalMinutes: 20,   // Refresh session setiap 20 menit
  maxWaitMs: 60000,             // Maksimal tunggu 60 detik per bypass
  checkIntervalMs: 2000,        // Periksa status setiap 2 detik
};

const colors = {
  reset: "\x1b[0m",
  bright: "\x1b[1m",
  cyan: "\x1b[36m",
  green: "\x1b[32m",
  yellow: "\x1b[33m",
  red: "\x1b[31m",
  magenta: "\x1b[35m",
  gray: "\x1b[90m",
};

function log(color, prefix, message) {
  const timestamp = new Date().toLocaleTimeString("id-ID");
  console.log(`${colors.gray}[${timestamp}]${colors.reset} ${color}[${prefix}]${colors.reset} ${message}`);
}

function logSuccess(msg) { log(colors.green, "SUKSES", msg); }
function logInfo(msg) { log(colors.cyan, "INFO", msg); }
function logWarn(msg) { log(colors.yellow, "PERINGATAN", msg); }
function logError(msg) { log(colors.red, "ERROR", msg); }

/**
 * Menyimpan data session ke file JSON
 */
function saveSession(sessionData) {
  const data = {
    ...sessionData,
    timestamp: new Date().toISOString(),
    expiresAt: new Date(Date.now() + CONFIG.refreshIntervalMinutes * 60 * 1000).toISOString(),
  };
  fs.writeFileSync(CONFIG.outputFile, JSON.stringify(data, null, 2), "utf-8");
  logSuccess(`Session disimpan ke: ${CONFIG.outputFile}`);
  return data;
}

/**
 * Fungsi utama: Bypass Cloudflare dan ekstrak session
 */
async function bypassCloudflare(browser) {
  logInfo(`Membuat konteks browser baru...`);

  const context = await browser.createBrowserContext().catch(() => null);
  if (!context) {
    logError("Gagal membuat konteks browser.");
    return null;
  }

  return new Promise(async (resolve) => {
    let isResolved = false;

    // Timeout keamanan
    const timeout = setTimeout(async () => {
      if (!isResolved) {
        isResolved = true;
        logError(`Timeout! Bypass tidak berhasil dalam ${CONFIG.maxWaitMs / 1000} detik.`);
        await context.close().catch(() => {});
        resolve(null);
      }
    }, CONFIG.maxWaitMs);

    try {
      const page = await context.newPage();

      logInfo(`Menavigasi ke: ${CONFIG.targetUrl}`);
      await page.goto(CONFIG.targetUrl, { waitUntil: "domcontentloaded" });

      logInfo("Menunggu Cloudflare Turnstile diselesaikan otomatis...");

      // Polling: periksa apakah cf_clearance cookie sudah ada
      const checkInterval = setInterval(async () => {
        if (isResolved) {
          clearInterval(checkInterval);
          return;
        }

        try {
          const cookies = await page.cookies();
          const cfClearance = cookies.find((c) => c.name === "cf_clearance");

          if (cfClearance) {
            clearInterval(checkInterval);
            clearTimeout(timeout);
            isResolved = true;

            // Ambil data tambahan
            const userAgent = await page.evaluate(() => navigator.userAgent);
            const allCookies = cookies;

            // Buat cookie string untuk digunakan di curl/axios
            const cookieString = cookies
              .map((c) => `${c.name}=${c.value}`)
              .join("; ");

            const sessionData = {
              cfClearance: cfClearance.value,
              userAgent: userAgent,
              cookies: allCookies,
              cookieString: cookieString,
              headers: {
                "user-agent": userAgent,
                cookie: cookieString,
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
                "accept-language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
              },
            };

            await context.close().catch(() => {});
            resolve(sessionData);
          }
        } catch (err) {
          // Abaikan error sementara
        }
      }, CONFIG.checkIntervalMs);
    } catch (err) {
      if (!isResolved) {
        isResolved = true;
        clearTimeout(timeout);
        logError(`Error saat bypass: ${err.message}`);
        await context.close().catch(() => {});
        resolve(null);
      }
    }
  });
}

/**
 * Loop utama: Jalankan bypass secara berkala
 */
async function main() {
  console.log(`\n${colors.cyan}${colors.bright}====================================================`);
  console.log("        AUTO BYPASS CLOUDFLARE - app.weavy.ai       ");
  console.log(`====================================================${colors.reset}`);
  console.log(`${colors.gray}Target  : ${CONFIG.targetUrl}`);
  console.log(`Refresh : Setiap ${CONFIG.refreshIntervalMinutes} menit`);
  console.log(`Output  : ${CONFIG.outputFile}${colors.reset}\n`);

  logInfo("Meluncurkan browser utama...");

  const { browser } = await connect({
    headless: false,
    turnstile: true,
    connectOption: { defaultViewport: null },
  });

  logSuccess("Browser berhasil diluncurkan!");

  let cycleCount = 0;

  async function runCycle() {
    cycleCount++;
    console.log(`\n${colors.magenta}${colors.bright}--- Siklus Bypass #${cycleCount} ---${colors.reset}`);

    const session = await bypassCloudflare(browser);

    if (session) {
      const saved = saveSession(session);

      logSuccess(`Cookie cf_clearance didapat!`);
      logInfo(`Nilai: ${session.cfClearance.substring(0, 50)}...`);
      logInfo(`User-Agent: ${session.userAgent}`);
      logInfo(`Jumlah cookies: ${session.cookies.length}`);
      logInfo(`Session berlaku hingga: ${saved.expiresAt}`);

      console.log(`\n${colors.green}${colors.bright}=== CONTOH PENGGUNAAN ===${colors.reset}`);
      console.log(`${colors.gray}Gunakan data berikut di skrip Anda:${colors.reset}`);
      console.log(`\n${colors.yellow}// Node.js (Fetch/Axios):${colors.reset}`);
      console.log(`const session = require("./session.json");`);
      console.log(`fetch("${CONFIG.targetUrl}", {`);
      console.log(`  headers: session.headers`);
      console.log(`});\n`);

      console.log(`${colors.yellow}// Curl:${colors.reset}`);
      console.log(`curl "${CONFIG.targetUrl}" \\`);
      console.log(`  -H "user-agent: ${session.userAgent.substring(0, 40)}..." \\`);
      console.log(`  -b "cf_clearance=${session.cfClearance.substring(0, 40)}..."\n`);
    } else {
      logWarn("Bypass gagal pada siklus ini. Akan mencoba lagi pada siklus berikutnya.");
    }

    // Jadwalkan siklus berikutnya
    const nextRefreshMs = CONFIG.refreshIntervalMinutes * 60 * 1000;
    logInfo(`Siklus berikutnya dalam ${CONFIG.refreshIntervalMinutes} menit...`);
    logInfo(`Tekan Ctrl+C untuk menghentikan bot.\n`);
    setTimeout(runCycle, nextRefreshMs);
  }

  // Tangani penutupan browser
  browser.on("disconnected", () => {
    logWarn("Browser terputus. Bot dihentikan.");
    process.exit(0);
  });

  // Tangani Ctrl+C
  process.on("SIGINT", async () => {
    logInfo("Menghentikan bot...");
    await browser.close().catch(() => {});
    process.exit(0);
  });

  // Mulai siklus pertama
  await runCycle();
}

main().catch((err) => {
  logError(`Fatal error: ${err.message}`);
  process.exit(1);
});
