"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.MailSentService = void 0;
const api_locale_1 = require("@hed-hog/api-locale");
const api_pagination_1 = require("@hed-hog/api-pagination");
const api_prisma_1 = require("@hed-hog/api-prisma");
const common_1 = require("@nestjs/common");
let MailSentService = class MailSentService {
    constructor(prismaService, paginationService) {
        this.prismaService = prismaService;
        this.paginationService = paginationService;
    }
    async list(paginationParams) {
        var _a, _b, _c, _d;
        const fields = ['subject', 'from', 'to', 'cc', 'bcc', 'body'];
        const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
        const AND = [];
        if (paginationParams.status &&
            paginationParams.status !== 'all' &&
            ['received', 'read', 'error'].includes(paginationParams.status)) {
            AND.push({
                mail_sent_user: {
                    some: {
                        status: paginationParams.status,
                    },
                },
            });
        }
        const recipientEmail = (_a = paginationParams.recipientEmail) === null || _a === void 0 ? void 0 : _a.trim();
        if (recipientEmail) {
            AND.push({
                mail_sent_user: {
                    some: {
                        recipient_email: {
                            contains: recipientEmail,
                            mode: 'insensitive',
                        },
                    },
                },
            });
        }
        const hasErrorRaw = (_b = paginationParams.hasError) === null || _b === void 0 ? void 0 : _b.trim().toLowerCase();
        if (hasErrorRaw === 'true' || hasErrorRaw === '1') {
            AND.push({
                mail_sent_user: {
                    some: {
                        status: 'error',
                    },
                },
            });
        }
        if (hasErrorRaw === 'false' || hasErrorRaw === '0') {
            AND.push({
                mail_sent_user: {
                    none: {
                        status: 'error',
                    },
                },
            });
        }
        const createdAt = {};
        const createdAtFrom = (_c = paginationParams.createdAtFrom) === null || _c === void 0 ? void 0 : _c.trim();
        const createdAtTo = (_d = paginationParams.createdAtTo) === null || _d === void 0 ? void 0 : _d.trim();
        if (createdAtFrom) {
            const parsedFrom = new Date(createdAtFrom);
            if (!isNaN(parsedFrom.getTime())) {
                createdAt.gte = parsedFrom;
            }
        }
        if (createdAtTo) {
            const parsedTo = new Date(createdAtTo);
            if (!isNaN(parsedTo.getTime())) {
                parsedTo.setHours(23, 59, 59, 999);
                createdAt.lte = parsedTo;
            }
        }
        if (paginationParams.search && !isNaN(+paginationParams.search)) {
            OR.push({ id: { equals: +paginationParams.search } });
        }
        const result = await this.paginationService.paginate(this.prismaService.mail_sent, paginationParams, {
            where: Object.assign(Object.assign(Object.assign({}, (OR.length > 0 ? { OR } : {})), (AND.length > 0 ? { AND } : {})), (Object.keys(createdAt).length > 0 ? { created_at: createdAt } : {})),
            include: {
                mail_sent_user: {
                    select: {
                        id: true,
                        recipient_email: true,
                        status: true,
                        read_at: true,
                        error_code: true,
                        error_message: true,
                        user_id: true,
                        user_identifier_id: true,
                        created_at: true,
                        updated_at: true,
                    },
                },
            },
        });
        const data = result.data.map((item) => {
            var _a;
            const recipientLogs = (_a = item.mail_sent_user) !== null && _a !== void 0 ? _a : [];
            const summary = recipientLogs.reduce((acc, recipient) => {
                if (recipient.status === 'received') {
                    acc.receivedCount += 1;
                }
                if (recipient.status === 'read') {
                    acc.readCount += 1;
                    if (recipient.read_at &&
                        (!acc.lastReadAt || recipient.read_at > acc.lastReadAt)) {
                        acc.lastReadAt = recipient.read_at;
                    }
                }
                if (recipient.status === 'error') {
                    acc.errorCount += 1;
                }
                return acc;
            }, {
                totalRecipients: recipientLogs.length,
                receivedCount: 0,
                readCount: 0,
                errorCount: 0,
                hasError: false,
                lastReadAt: null,
            });
            summary.hasError = summary.errorCount > 0;
            return Object.assign(Object.assign({}, item), { deliverySummary: summary });
        });
        return Object.assign(Object.assign({}, result), { data });
    }
    async get(locale, id) {
        const mailSent = await this.prismaService.mail_sent.findUnique({
            where: { id: id },
        });
        if (!mailSent) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('mail_sent_not_found', locale));
        }
        return mailSent;
    }
    async create({ body, from, mail_id, subject, bcc, cc, to }) {
        if (!body || !mail_id || !subject || !to) {
            throw new common_1.BadRequestException('All fields are required.');
        }
        if (Array.isArray(cc)) {
            cc = cc.join(';');
        }
        if (Array.isArray(bcc)) {
            bcc = bcc.join(';');
        }
        if (Array.isArray(to)) {
            to = to.join(';');
        }
        return this.prismaService.mail_sent.create({
            data: {
                mail_id: mail_id,
                subject: subject,
                from: from !== null && from !== void 0 ? from : 'mail@mail.com',
                to: to,
                cc: cc,
                bcc: bcc,
                body: body,
            },
        });
    }
    async update(locale, { id, data }) {
        const mailSent = await this.prismaService.mail_sent.findUnique({
            where: { id: id },
        });
        if (!mailSent) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('mail_sent_not_found', locale));
        }
        return this.prismaService.mail_sent.update({
            where: { id: id },
            data,
        });
    }
    async delete(locale, { ids }) {
        if (ids == undefined || ids == null) {
            throw new common_1.BadRequestException('You must select at least one item to delete.');
        }
        const mailSent = await this.prismaService.mail_sent.findMany({
            where: {
                id: {
                    in: ids,
                },
            },
        });
        if (mailSent.length !== ids.length) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('mail_sent_not_found', locale));
        }
        return this.prismaService.mail_sent.deleteMany({
            where: {
                id: {
                    in: ids,
                },
            },
        });
    }
};
exports.MailSentService = MailSentService;
exports.MailSentService = MailSentService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),
    __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_pagination_1.PaginationService))),
    __metadata("design:paramtypes", [api_prisma_1.PrismaService,
        api_pagination_1.PaginationService])
], MailSentService);
//# sourceMappingURL=mail-sent.service.js.map