import { Injectable, type OnModuleInit } from '@nestjs/common';
import {
  apps,
  initializeApp,
  credential,
  messaging,
  type ServiceAccount,
} from 'firebase-admin';
import { LoggerService } from '@modules/shared';

export interface SendPushDto {
  token: string;
  title: string;
  body: string;
  data?: Record<string, string>;
}

@Injectable()
export class FcmService implements OnModuleInit {
  private initialized = false;

  constructor(private readonly logger: LoggerService) {}

  onModuleInit(): void {
    const serviceAccountJson = process.env['FIREBASE_SERVICE_ACCOUNT'];
    if (!serviceAccountJson) {
      this.logger.warn(
        'FIREBASE_SERVICE_ACCOUNT not set — push notifications disabled',
        'FcmService',
      );
      return;
    }

    try {
      const serviceAccount = JSON.parse(serviceAccountJson) as ServiceAccount;
      if (!apps.length) {
        initializeApp({ credential: credential.cert(serviceAccount) });
      }
      this.initialized = true;
      this.logger.log('Firebase Admin initialized for push notifications', 'FcmService');
    } catch (error) {
      this.logger.error(
        `Failed to initialize Firebase: ${error instanceof Error ? error.message : String(error)}`,
        'FcmService',
      );
    }
  }

  get isAvailable(): boolean {
    return this.initialized;
  }

  async send(dto: SendPushDto): Promise<string> {
    if (!this.initialized) {
      throw new Error('FCM not initialized — FIREBASE_SERVICE_ACCOUNT not configured');
    }

    try {
      const messageId = await messaging().send({
        token: dto.token,
        notification: {
          title: dto.title,
          body: dto.body,
        },
        data: dto.data,
        android: { priority: 'high' },
        apns: { payload: { aps: { sound: 'default' } } },
      });

      this.logger.log(`Push sent to token ${dto.token.slice(0, 10)}...: ${messageId}`, 'FcmService');
      return messageId;
    } catch (error) {
      this.logger.error(
        `Failed to send push: ${error instanceof Error ? error.message : String(error)}`,
        'FcmService',
      );
      throw error;
    }
  }
}
