"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var NotificationsService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NotificationsService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const enums_1 = require("../../common/enums");
const notification_entity_1 = require("../../database/entities/notification.entity");
const notification_preferences_entity_1 = require("../../database/entities/notification-preferences.entity");
let NotificationsService = NotificationsService_1 = class NotificationsService {
    constructor(notificationRepo, notificationPrefsRepo) {
        this.notificationRepo = notificationRepo;
        this.notificationPrefsRepo = notificationPrefsRepo;
        this.logger = new common_1.Logger(NotificationsService_1.name);
    }
    async notify(input) {
        try {
            const prefs = await this.notificationPrefsRepo.findOne({
                where: { userId: input.userId },
            });
            if (prefs && input.type === enums_1.NotificationType.Expense && !prefs.expenseAdded)
                return;
            if (prefs && input.type === enums_1.NotificationType.Settlement && !prefs.settlementReminder)
                return;
            const notification = this.notificationRepo.create({
                userId: input.userId,
                title: input.title,
                body: input.body,
                type: input.type,
                entityId: input.entityId,
            });
            await this.notificationRepo.save(notification);
        }
        catch (err) {
            this.logger.error('Failed to create notification', err);
        }
    }
    async notifyMany(userIds, input) {
        await Promise.all(userIds.map((userId) => this.notify({ ...input, userId })));
    }
    async list(userId, query) {
        const page = query.page ?? 1;
        const limit = query.limit ?? 20;
        const skip = (page - 1) * limit;
        const [notifications, total, unreadCount] = await Promise.all([
            this.notificationRepo.find({
                where: { userId },
                order: { createdAt: 'DESC' },
                skip,
                take: limit,
            }),
            this.notificationRepo.count({ where: { userId } }),
            this.notificationRepo.count({ where: { userId, isRead: false } }),
        ]);
        const totalPages = Math.ceil(total / limit);
        return {
            data: notifications.map(this.toDto),
            total,
            unreadCount,
            page,
            limit,
            totalPages,
            hasNextPage: page < totalPages,
        };
    }
    async markRead(notificationId, userId) {
        const notification = await this.notificationRepo.findOne({
            where: { id: notificationId },
        });
        if (!notification)
            throw new common_1.NotFoundException('Notification not found');
        if (notification.userId !== userId)
            throw new common_1.ForbiddenException('Access denied');
        await this.notificationRepo.update({ id: notificationId }, { isRead: true });
        const updated = await this.notificationRepo.findOne({ where: { id: notificationId } });
        if (!updated)
            throw new common_1.NotFoundException('Notification not found');
        return this.toDto(updated);
    }
    async markAllRead(userId) {
        const result = await this.notificationRepo.update({ userId, isRead: false }, { isRead: true });
        return { message: `Marked ${result.affected ?? 0} notification(s) as read`, count: result.affected ?? 0 };
    }
    toDto(n) {
        return {
            id: n.id,
            title: n.title,
            body: n.body,
            type: n.type,
            entityId: n.entityId,
            isRead: n.isRead,
            createdAt: n.createdAt,
        };
    }
};
exports.NotificationsService = NotificationsService;
exports.NotificationsService = NotificationsService = NotificationsService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(notification_entity_1.Notification)),
    __param(1, (0, typeorm_1.InjectRepository)(notification_preferences_entity_1.NotificationPreferences)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository])
], NotificationsService);
//# sourceMappingURL=notifications.service.js.map