/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { NotificationDocument } from '@schemas/notification.schema';
import { UserDocument } from '@schemas/user.schema';
import * as admin from 'firebase-admin';
import * as fs from 'fs';
import * as path from 'path';
import { Model } from 'mongoose';
import { CreateNotificationDto } from '@dtos/create-notification.dto';
import { Notify } from '@common/cron.interface';

const serviceAccount = JSON.parse(
  fs.readFileSync(
    path.resolve(
      process.cwd(),
      'src/common/firebase/loteria-d4211-firebase-adminsdk-fbsvc-91e2de9e03.json',
    ),
    'utf8',
  ),
);

@Injectable()
export class NotificationsService {
  private messaging: admin.messaging.Messaging;

  constructor(
    @InjectModel('users') private userModel: Model<UserDocument>,
    @InjectModel('notifications')
    private notificationModel: Model<NotificationDocument>,
  ) {
    if (!admin.apps.length) {
      admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
      });
    }
    this.messaging = admin.messaging();
  }

  async create(data: CreateNotificationDto) {
    const user = await this.userModel.findById(data.userId).exec();
    if (!user) {
      throw new HttpException('Datos incorrectos', HttpStatus.NOT_FOUND);
    }

    if (user.token !== '') {
      await this.sendNotification(data, user.token);
    }

    const newNotification = new this.notificationModel(data);
    return newNotification.save();
  }

  async createCronNotification(data: Notify) {
    const newNotification = new this.notificationModel(data);
    return newNotification.save();
  }

  async createCronNotificationPush(data: Notify, token: string) {
    await this.sendNotification(data, token);
  }

  async getAll(userId: string) {
    const user = await this.userModel.findById(userId).exec();
    if (!user) {
      throw new HttpException('Datos incorrectos', HttpStatus.BAD_REQUEST);
    }

    return await this.notificationModel
      .find({ userId: user._id })
      .sort({ createdAt: -1 })
      .populate('userId')
      .skip(0)
      .limit(20)
      .exec();
  }

  async remove(id: string) {
    const result = await this.notificationModel.findByIdAndDelete(id);
    if (!result)
      throw new HttpException('Datos incorrectos', HttpStatus.BAD_REQUEST);
    return { message: 'Eliminado' };
  }

  private async sendNotification(pl: any, token: string) {
    const payload = {
      token,
      notification: {
        title: pl.title,
        body: pl.body,
        image: process.env.URL_BACKEND + '/etc/preview.jpg',
      },
      data: pl.data,
    };

    try {
      const response = await this.messaging.send(payload);
      console.log('Notificación enviada:', response);
      return { success: true, response };
    } catch (error) {
      console.error('Error enviando notificación:', error);
      return { success: false, error };
    }
  }
}
