"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); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UsersService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const user_entity_1 = require("../../database/entities/user.entity");
const group_member_entity_1 = require("../../database/entities/group-member.entity");
const notification_preferences_entity_1 = require("../../database/entities/notification-preferences.entity");
const enums_1 = require("../../common/enums");
let UsersService = class UsersService {
    constructor(userRepo, groupMemberRepo, notificationPrefsRepo) {
        this.userRepo = userRepo;
        this.groupMemberRepo = groupMemberRepo;
        this.notificationPrefsRepo = notificationPrefsRepo;
    }
    async getMe(userId) {
        const user = await this.userRepo.findOne({
            where: { id: userId },
            relations: { notificationPreferences: true },
        });
        if (!user)
            throw new common_1.NotFoundException('User not found');
        return this.toDto(user);
    }
    async updateMe(userId, dto) {
        await this.userRepo.update({ id: userId }, {
            ...(dto.name !== undefined && { name: dto.name }),
            ...(dto.currency !== undefined && { currency: dto.currency }),
            ...(dto.timezone !== undefined && { timezone: dto.timezone }),
            ...(dto.darkMode !== undefined && { darkMode: dto.darkMode }),
            ...(dto.avatarUrl !== undefined && { avatarUrl: dto.avatarUrl }),
        });
        return this.getMe(userId);
    }
    async updatePreferences(userId, dto) {
        let prefs = await this.notificationPrefsRepo.findOne({ where: { userId } });
        if (prefs) {
            if (dto.expenseAdded !== undefined)
                prefs.expenseAdded = dto.expenseAdded;
            if (dto.settlementReminder !== undefined)
                prefs.settlementReminder = dto.settlementReminder;
            if (dto.emailNotifications !== undefined)
                prefs.emailNotifications = dto.emailNotifications;
            if (dto.pushNotifications !== undefined)
                prefs.pushNotifications = dto.pushNotifications;
            await this.notificationPrefsRepo.save(prefs);
        }
        else {
            prefs = this.notificationPrefsRepo.create({
                userId,
                expenseAdded: dto.expenseAdded ?? true,
                settlementReminder: dto.settlementReminder ?? true,
                emailNotifications: dto.emailNotifications ?? true,
                pushNotifications: dto.pushNotifications ?? false,
            });
            await this.notificationPrefsRepo.save(prefs);
        }
        return this.getMe(userId);
    }
    async deleteMe(userId) {
        const user = await this.userRepo.findOne({ where: { id: userId } });
        if (!user)
            throw new common_1.NotFoundException('User not found');
        const adminMemberships = await this.groupMemberRepo.find({
            where: {
                userId,
                role: enums_1.GroupRole.Admin,
                leftAt: (0, typeorm_2.IsNull)(),
                group: { isActive: true },
            },
            relations: { group: true },
        });
        let blockedCount = 0;
        for (const membership of adminMemberships) {
            const adminCount = await this.groupMemberRepo.count({
                where: { groupId: membership.groupId, role: enums_1.GroupRole.Admin, leftAt: (0, typeorm_2.IsNull)() },
            });
            if (adminCount === 1)
                blockedCount += 1;
        }
        if (blockedCount > 0) {
            throw new common_1.BadRequestException(`You are the sole admin of ${blockedCount} group(s). Transfer admin rights before deleting your account.`);
        }
        await this.userRepo.delete({ id: userId });
        return { message: 'Account deleted successfully' };
    }
    async search(query, requesterId) {
        if (!query || query.trim().length < 2)
            return [];
        const users = await this.userRepo.find({
            where: [
                { id: (0, typeorm_2.Not)(requesterId), name: (0, typeorm_2.Like)(`%${query}%`) },
                { id: (0, typeorm_2.Not)(requesterId), email: (0, typeorm_2.Like)(`%${query}%`) },
            ],
            select: { id: true, name: true, email: true, avatarUrl: true },
            take: 10,
        });
        return users;
    }
    toDto(user) {
        return {
            id: user.id,
            email: user.email,
            name: user.name,
            avatarUrl: user.avatarUrl,
            currency: user.currency,
            timezone: user.timezone,
            darkMode: user.darkMode,
            isEmailVerified: user.isEmailVerified,
            createdAt: user.createdAt,
            notificationPreferences: user.notificationPreferences ?? null,
        };
    }
};
exports.UsersService = UsersService;
exports.UsersService = UsersService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(user_entity_1.User)),
    __param(1, (0, typeorm_1.InjectRepository)(group_member_entity_1.GroupMember)),
    __param(2, (0, typeorm_1.InjectRepository)(notification_preferences_entity_1.NotificationPreferences)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository])
], UsersService);
//# sourceMappingURL=users.service.js.map