"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.MessagesService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const message_entity_1 = require("./message.entity");
const connection_entity_1 = require("../network/connection.entity");
let MessagesService = class MessagesService {
    constructor(messageRepo, connectionRepo) {
        this.messageRepo = messageRepo;
        this.connectionRepo = connectionRepo;
    }
    async checkConnection(userId, otherUserId) {
        const connection = await this.connectionRepo.findOne({
            where: [
                { user: { id: userId }, connection: { id: otherUserId }, status: 'accepted' },
                { user: { id: otherUserId }, connection: { id: userId }, status: 'accepted' }
            ]
        });
        return !!connection;
    }
    async sendMessage(senderId, recipientId, content) {
        const areConnected = await this.checkConnection(senderId, recipientId);
        if (!areConnected) {
            throw new common_1.BadRequestException('You can only message users you are connected with');
        }
        const message = this.messageRepo.create({
            sender: { id: senderId },
            recipient: { id: recipientId },
            content,
            isRead: false
        });
        return this.messageRepo.save(message);
    }
    async getConversation(userId, otherUserId) {
        const areConnected = await this.checkConnection(userId, otherUserId);
        if (!areConnected) {
            throw new common_1.BadRequestException('You can only view conversations with connected users');
        }
        const messages = await this.messageRepo.find({
            where: [
                { sender: { id: userId }, recipient: { id: otherUserId } },
                { sender: { id: otherUserId }, recipient: { id: userId } }
            ],
            order: { createdAt: 'ASC' }
        });
        return messages;
    }
    async getConversations(userId) {
        const messages = await this.messageRepo
            .createQueryBuilder('message')
            .leftJoinAndSelect('message.sender', 'sender')
            .leftJoinAndSelect('message.recipient', 'recipient')
            .where('message.senderId = :userId OR message.recipientId = :userId', { userId })
            .orderBy('message.createdAt', 'DESC')
            .getMany();
        const conversationsMap = new Map();
        for (const message of messages) {
            const partnerId = message.sender.id === userId ? message.recipient.id : message.sender.id;
            if (!conversationsMap.has(partnerId)) {
                const partner = message.sender.id === userId ? message.recipient : message.sender;
                conversationsMap.set(partnerId, {
                    user: {
                        id: partner.id,
                        name: partner.name,
                        avatarUrl: partner.avatarUrl,
                        userType: partner.userType
                    },
                    lastMessage: message,
                    unreadCount: 0
                });
            }
            if (message.recipient.id === userId && !message.isRead) {
                conversationsMap.get(partnerId).unreadCount++;
            }
        }
        return Array.from(conversationsMap.values());
    }
    async markAsRead(messageId, userId) {
        const message = await this.messageRepo.findOne({ where: { id: messageId } });
        if (!message) {
            throw new common_1.NotFoundException('Message not found');
        }
        if (message.recipient.id !== userId) {
            throw new common_1.BadRequestException('You can only mark your own messages as read');
        }
        message.isRead = true;
        return this.messageRepo.save(message);
    }
    async markConversationAsRead(userId, otherUserId) {
        await this.messageRepo
            .createQueryBuilder()
            .update(message_entity_1.MessageEntity)
            .set({ isRead: true })
            .where('recipientId = :userId AND senderId = :otherUserId AND isRead = false', {
            userId,
            otherUserId
        })
            .execute();
        return { success: true };
    }
};
exports.MessagesService = MessagesService;
exports.MessagesService = MessagesService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(message_entity_1.MessageEntity)),
    __param(1, (0, typeorm_1.InjectRepository)(connection_entity_1.ConnectionEntity)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository])
], MessagesService);
//# sourceMappingURL=messages.service.js.map