import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { LoggingService } from 'src/database/logging/logging.service';
import { NOTIFICATION_EVENT } from './model/notification-event.type';
import { NOTIFICATION_EVENT_NAME } from './events/notification-event-names';
import { PlayerActiveChangedEvent } from './events/player-active-changed.event';
import { PlayerRoleChangedEvent } from './events/player-role-changed.event';
import { PlayerCreatedEvent } from './events/player-created.event';
import { PublicAccessEnabledEvent, PublicAccessRotatedEvent } from './events/public-access-changed.event';
import { InviteLinkCreatedEvent } from './events/invite-link-created.event';
import { NotificationsService } from './notifications.service';

@Injectable()
export class NotificationsListener {
  constructor(
    private readonly notifications: NotificationsService,
    private readonly logger: LoggingService,
  ) {}

  @OnEvent(NOTIFICATION_EVENT_NAME.playerActiveChanged)
  onPlayerActiveChanged(event: PlayerActiveChangedEvent): Promise<void> {
    return this.safeCreate('player_active_update', event.teamId, event.actorUserId, {
      playerId: event.playerId,
      playerName: event.playerName,
      active: event.active,
    });
  }

  @OnEvent(NOTIFICATION_EVENT_NAME.playerRoleChanged)
  onPlayerRoleChanged(event: PlayerRoleChangedEvent): Promise<void> {
    return this.safeCreate('player_team_role_update', event.teamId, event.actorUserId, {
      playerId: event.playerId,
      playerName: event.playerName,
      teamRoleId: event.teamRoleId,
    });
  }

  @OnEvent(NOTIFICATION_EVENT_NAME.playerCreated)
  onPlayerCreated(event: PlayerCreatedEvent): Promise<void> {
    return this.safeCreate('player_creation', event.teamId, event.actorUserId, {
      playerId: event.playerId,
      playerName: event.playerName,
    });
  }

  @OnEvent(NOTIFICATION_EVENT_NAME.publicAccessEnabled)
  onPublicAccessEnabled(event: PublicAccessEnabledEvent): Promise<void> {
    return this.safeCreate('public_access_enabled', event.teamId, event.actorUserId, {});
  }

  @OnEvent(NOTIFICATION_EVENT_NAME.publicAccessRotated)
  onPublicAccessRotated(event: PublicAccessRotatedEvent): Promise<void> {
    return this.safeCreate('public_access_rotated', event.teamId, event.actorUserId, {});
  }

  @OnEvent(NOTIFICATION_EVENT_NAME.inviteLinkCreated)
  onInviteLinkCreated(event: InviteLinkCreatedEvent): Promise<void> {
    return this.safeCreate('user_invite_link_create', event.teamId, event.actorUserId, {
      teamName: event.teamName,
    });
  }

  private async safeCreate(
    event: NOTIFICATION_EVENT,
    teamId: number,
    actorUserId: number,
    payload: Record<string, unknown>,
  ): Promise<void> {
    try {
      await this.notifications.create({ teamId, event, actorUserId, payload });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      await this.logger.error({
        event: 'notification_create_fail',
        details: `teamId=${teamId} event=${event}: ${errorMessage}`,
        userId: -1,
      });
    }
  }
}
