import * as admin from 'firebase-admin';
import { Injectable } from '@nestjs/common';

@Injectable()
export class FirebaseService {
  constructor() {
    if (!admin.apps.length) {
      admin.initializeApp({
        credential: admin.credential.cert({
          projectId: process.env.FIREBASE_PROJECT_ID,
          clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
          privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n'),
        }),
      });
    }
  }

  async sendToDevice(token: string, payload: any) {
    const res = await admin.messaging().send({
      token,
      data: {
        title: String(payload.title),
        body: String(payload.body),
      },
    });
    return res;
  }

  async sendToMultipleDevices(tokens: string[], payload: any) {
    if (!tokens.length) return;

    const res = await admin.messaging().sendEachForMulticast({
      tokens,
      data: {
        title: String(payload.title),
        body: String(payload.body),
      },
      notification: {
        title: payload.title,
        body: payload.body,
      },
      android: {
        priority: 'high',
        notification: {
          channelId: 'default',
        },
      },
    });

    return res;
  }

  async sendAndCleanup(
    tokens: string[],
    payload: any,
    removeFn: (token: string) => Promise<void>,
  ) {
    if (!tokens.length) return;

    const res = await admin.messaging().sendEachForMulticast({
      tokens,
      data: {
        title: String(payload.title),
        body: String(payload.body),
      },
    });

    await Promise.all(
      res.responses.map(async (r, index) => {
        if (!r.success) {
          const error = r.error?.code;

          if (
            error === 'messaging/registration-token-not-registered' ||
            error === 'messaging/invalid-registration-token'
          ) {
            const badToken = tokens[index];
            await removeFn(badToken);
          }
        }
      }),
    );

    return res;
  }
}
