import { ForbiddenException, Injectable } from '@nestjs/common';
import { NotificationChannel, UserRole } from '@prisma/client';
import { PrismaService } from '../database/prisma.service';
import { MessagingService } from '../messaging/messaging.service';
import { OrdersGateway } from '../orders/orders.gateway';
import { CreateNotificationDto } from './dto/create-notification.dto';

type RequestUser = {
  sub: string;
  role: UserRole;
};

@Injectable()
export class NotificationsService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly ordersGateway: OrdersGateway,
    private readonly messagingService: MessagingService,
  ) {}

  list(user: RequestUser) {
    return this.prisma.notification.findMany({
      where: user.role === UserRole.ADMIN || user.role === UserRole.SUPER_ADMIN ? undefined : { userId: user.sub },
      include: {
        user: {
          select: {
            email: true,
            phone: true,
            role: true,
          },
        },
      },
      orderBy: { createdAt: 'desc' },
      take: 200,
    });
  }

  async createAdminNotification(actor: RequestUser, body: CreateNotificationDto) {
    if (actor.role !== UserRole.ADMIN && actor.role !== UserRole.SUPER_ADMIN) {
      throw new ForbiddenException('Somente o admin pode disparar notificacoes manuais.');
    }

    let targetUsers: Array<{ id: string; role: UserRole }> = [];
    if (body.userId) {
      const user = await this.prisma.user.findUnique({ where: { id: body.userId }, select: { id: true, role: true } });
      if (user) {
        targetUsers = [user];
      }
    } else if (body.role) {
      targetUsers = await this.prisma.user.findMany({
        where: { role: body.role },
        select: { id: true, role: true },
        take: 50,
      });
    }

    const created = await this.prisma.notification.createMany({
      data: targetUsers.map((user) => ({
        userId: user.id,
        title: body.title,
        body: body.body,
        channel: body.channel,
        payload: {
          source: 'admin-console',
          targetRole: body.role ?? null,
          createdBy: actor.sub,
        },
      })),
    });

    targetUsers.forEach((user) => {
      this.ordersGateway.emitToUser(user.id, 'notification.created', {
        title: body.title,
        body: body.body,
        channel: body.channel,
        userId: user.id,
      });
      this.ordersGateway.emitToRole(user.role, 'notification.created', {
        title: body.title,
        body: body.body,
        channel: body.channel,
        role: user.role,
      });
    });

    return {
      ok: true,
      created: created.count,
      targetRole: body.role ?? null,
      targetUserId: body.userId ?? null,
      channel: body.channel,
    };
  }

  async getPushProviders() {
    return [
      { provider: 'Firebase Cloud Messaging', channel: NotificationChannel.PUSH, mode: 'prepared' },
      { provider: 'Email transacional', channel: NotificationChannel.EMAIL, mode: 'prepared' },
      { provider: 'SMS', channel: NotificationChannel.SMS, mode: 'prepared' },
      { ...(await this.messagingService.getWascriptProviderStatus()), channel: NotificationChannel.SMS },
      { provider: 'Inbox interno', channel: NotificationChannel.IN_APP, mode: 'active' },
    ];
  }
}
