import { initializeApp, cert } from "firebase-admin/app";
import { getMessaging } from "firebase-admin/messaging";

// Inisialisasi Firebase Admin
const serviceAccount = require("./key.json");

try {
  initializeApp({
    credential: cert(serviceAccount),
  });
  console.log("Firebase berhasil diinisialisasi");
} catch (error) {
  console.error("Gagal inisialisasi Firebase:", (error as Error).message);
  process.exit(1);
}

// Fungsi untuk menguji koneksi ke FCM server
async function testFCMConnection(): Promise<boolean> {
  try {
    const response = await fetch("https://fcm.googleapis.com", { method: "GET" });
    console.log("Koneksi ke FCM server:", response.status, response.statusText);
    return response.ok;
  } catch (error) {
    console.error("Gagal menghubungi FCM server:", (error as Error).message);
    return false;
  }
}

// Fungsi untuk mengirim notifikasi ke banyak perangkat dengan retry
async function sendFCMEach(maxRetries: number = 5, retryDelay: number = 2000): Promise<any> {
  try {
    // Token perangkat
    const tokens: string[] = [
      "c89yuexsS_uc1tOErVPu5a:APA91bEb6tEKXAfReZjFVJ2mMyOzoW_RXryLSnSJTpbIVV3G0L_DCNkLuRvJ02Ip-Erz88QCQBAt-C2SN8eCRxu3-v1sBzXzKPtDv-huXpkjXsyrkifqvUo",
      "cRz96GHKTRaQaRJ35e8Hxa:APA91bEUSxE0VPbqKSzseQ_zGhbYsDofMexKykRw7o_3z2aPM9YFmZbeA2enrmb3qjdZ2g4-QQtiNHAyaZqAT1ITOrwo9jVJlShTeABmEFYP5GLEUZ3dlLc",
    ];

    // Validasi token sebelum mengirim
    const validTokens: string[] = [];
    for (const token of tokens) {
      try {
        await getMessaging().send({
          token,
          notification: { title: "Test", body: "Validasi token" },
        });
        validTokens.push(token);
        console.log(`Token ${token.slice(-4)} valid`);
      } catch (error) {
        console.error(`Token ${token.slice(-4)} tidak valid:`, (error as Error).message);
      }
    }

    if (validTokens.length === 0) {
      throw new Error("Tidak ada token valid untuk mengirim notifikasi");
    }

    // Buat pesan untuk setiap token
    const messages = validTokens.map((token) => ({
      notification: {
        title: "Judul Notifikasi",
        body: `Pesan untuk perangkat ${token.slice(-4)}`,
      },
      token,
      data: {
        key1: "value1",
        key2: "value2",
      },
      android: {
        priority: "high",
        notification: {
          sound: "default",
          channelId: "default_channel",
        },
      },
      apns: {
        payload: {
          aps: {
            sound: "default",
          },
        },
      },
    }));

    console.log("Mengirim notifikasi ke token:", validTokens.map((t) => t.slice(-4)));

    // Cek koneksi ke FCM server
    const isConnected = await testFCMConnection();
    if (!isConnected) {
      throw new Error("Gagal terhubung ke FCM server. Periksa jaringan atau firewall.");
    }

    // Kirim pesan dengan retry logic
    let lastError: any;
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        const response = await getMessaging().sendEach(messages as any);
        console.log("Notifikasi berhasil dikirim:", response.successCount);
        console.log("Notifikasi gagal:", response.failureCount);

        response.responses.forEach((resp: any, index: number) => {
          if (resp.success) {
            console.log(`Pesan ke ${validTokens[index].slice(-4)} berhasil:`, resp.messageId);
          } else {
            console.error(
              `Pesan ke ${validTokens[index].slice(-4)} gagal:`,
              resp.error?.code,
              resp.error?.message
            );
          }
        });

        return response;
      } catch (error) {
        lastError = error;
        console.error(`Percobaan ${attempt} gagal:`, (error as Error).message);
        if (error instanceof Error && (error as any).code === "app/network-error" && attempt < maxRetries) {
          console.log(`Menunggu ${retryDelay}ms sebelum mencoba lagi...`);
          await new Promise((resolve) => setTimeout(resolve, retryDelay));
        } else {
          throw new Error(`Gagal setelah ${maxRetries} percobaan: ${(error as Error).message}`);
        }
      }
    }
    throw lastError;
  } catch (error) {
    console.error("Error mengirim notifikasi:", (error as Error).message, (error as Error).stack);
    if ((error as any).code === "messaging/registration-token-not-registered") {
      console.log("Token tidak valid. Hapus token dari database.");
    }
    throw error;
  }
}

// Jalankan fungsi
async function main() {
  try {
    await sendFCMEach();
    console.log("Proses selesai");
  } catch (error) {
    console.error("Gagal menjalankan sendFCMEach:", (error as Error).message);
    process.exit(1);
  }
}

main();