import { BadRequestException, Injectable, NotFoundException, Inject, forwardRef } from '@nestjs/common'; import { CreatePagerDto } from '../dto/create-pager.dto'; import { User } from '../../users/entities/user.entity'; import { EntityManager } from '@mikro-orm/postgresql'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { Pager } from '../entities/pager.entity'; import { PagerStatus } from '../interface/pager'; import { ulid } from 'ulid'; import { Admin } from '../../admin/entities/admin.entity'; import { PagerCreatedEvent } from '../events/pager.events'; import { EventEmitter2 } from '@nestjs/event-emitter'; @Injectable() export class PagerService { constructor( private readonly em: EntityManager, // @Inject(forwardRef(() => PagerGateway)) // private readonly pagerGateway: PagerGateway, private readonly eventEmitter: EventEmitter2, ) {} async create( createPagerDto: CreatePagerDto, params: { restId?: string; userId?: string; slug: string; userCookieId?: string }, ) { const { restId, userId, slug, userCookieId } = params; let restaurant: Restaurant | null = null; let user: User | null = null; if (!restId && !userId && !slug) { throw new BadRequestException('Invalid parameters'); } if (restId) { restaurant = await this.em.findOne(Restaurant, { id: restId }); if (!restaurant) { throw new NotFoundException('Restaurant not found'); } } if (userId) { user = await this.em.findOne(User, { id: userId }); if (!user) { throw new NotFoundException('User not found'); } } if (!restaurant && slug) { restaurant = await this.em.findOne(Restaurant, { slug }); if (!restaurant) { throw new NotFoundException('Restaurant not found'); } } const cookieId = userCookieId || ulid().toString(); // const existingPager = await this.em.findOne(Pager, { // restaurant: { id: restaurant!.id }, // status: PagerStatus.Pending, // cookieId, // }); // if (existingPager) { // throw new BadRequestException('Pager already exists'); // } const pager = this.em.create(Pager, { ...createPagerDto, restaurant: restaurant!, user, cookieId: ulid().toString(), status: PagerStatus.Pending, }); await this.em.persistAndFlush(pager); // Populate relations before emitting await this.em.populate(pager, ['restaurant']); // Emit socket event for new pager this.eventEmitter.emit(PagerCreatedEvent.name, new PagerCreatedEvent(pager.restaurant.id, pager.tableNumber)); return pager; } async findAll(cookieId: string) { const pagers = await this.em.find(Pager, { cookieId }, { populate: ['user'] }); return pagers; } async findAllByRestaurantId(restId: string) { const pagers = await this.em.find(Pager, { restaurant: { id: restId } }, { populate: ['user'] }); return pagers; } async updateStatus(pagerId: string, restId: string, staffId: string, status: PagerStatus) { const pager = await this.em.findOne( Pager, { id: pagerId, restaurant: { id: restId } }, { populate: ['restaurant'] }, ); if (!pager) { throw new NotFoundException('Pager not found *'); } const staff = await this.em.findOne(Admin, { id: staffId }); if (!staff) { throw new NotFoundException('Staff not found'); } pager.status = status; if (status === PagerStatus.Acknowledged) { pager.staff = staff; } await this.em.persistAndFlush(pager); // Populate relations before emitting await this.em.populate(pager, ['restaurant', 'staff', 'user']); // Emit socket event for status update // this.pagerGateway.emitPagerStatusUpdated(pager); return pager; } }