"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UiNotificationService = exports.UI_NOTIFICATION_ERROR_PREFIX = void 0;
exports.isUiNotificationError = isUiNotificationError;
const test_1 = require("@playwright/test");
const logger_1 = require("../../../utils/logger");
const notification_messages_1 = require("../../../notification.messages");
const timeouts_1 = require("../../../timeouts");
/** Префикс сообщений о toast-ошибках; для распознавания в catch-блоках вызывающего кода. */
exports.UI_NOTIFICATION_ERROR_PREFIX = 'Обнаружены уведомления об ошибках';
/**
 * Проверяет, что исключение — сообщение о toast-ошибке из {@link UiNotificationService}.
 */
function isUiNotificationError(error) {
    return error instanceof Error && error.message.startsWith(exports.UI_NOTIFICATION_ERROR_PREFIX);
}
/**
 * Поиск и проверка toast-уведомлений об ошибках и успехе на UI.
 */
class UiNotificationService {
    constructor(page) {
        this.page = page;
    }
    async findVisibleErrors() {
        const errorElements = await this.page.getByTestId('notification_error').all();
        const visibilityResults = await Promise.all(errorElements.map(async (element) => ({
            element,
            visible: await element.isVisible(),
        })));
        const errorMessages = await Promise.all(visibilityResults
            .filter(r => r.visible)
            .map(async (r) => {
            const textContent = await r.element.textContent();
            return textContent ? textContent.replace(/Ошибка/g, '').trim() : '';
        }));
        return errorMessages.filter(msg => msg !== '');
    }
    async tryFindErrors() {
        const visibleErrors = await this.findVisibleErrors();
        if (visibleErrors.length > 0) {
            return visibleErrors;
        }
    }
    /**
     * Формирует текст ошибки по найденным toast-уведомлениям.
     * @param errors — тексты видимых уведомлений об ошибке
     * @param options.actionDescription — описание действия в предложном падеже
     * @param options.includeUrl — добавить URL страницы в сообщение
     */
    formatErrorsMessage(errors, options) {
        const quotedErrors = errors.map(msg => `"${msg}"`).join('; ');
        let message = options?.actionDescription
            ? `${exports.UI_NOTIFICATION_ERROR_PREFIX} при ${options.actionDescription}: ${quotedErrors}`
            : `${exports.UI_NOTIFICATION_ERROR_PREFIX} на странице: ${quotedErrors}`;
        if (options?.includeUrl) {
            message += `. URL: ${this.page.url()}`;
        }
        return message;
    }
    /**
     * Проверяет видимые toast-ошибки и бросает исключение, если они найдены.
     * @param options — контекст действия и опции сообщения
     */
    async throwIfErrorsFound(options) {
        const errors = await this.tryFindErrors();
        if (errors) {
            throw new Error(this.formatErrorsMessage(errors, options));
        }
    }
    /**
     * Выполняет действие; после завершения и при ошибке проверяет toast-уведомления UI.
     * @param actionDescription — описание действия в предложном падеже, например «сохранении блока X»
     * @param action — шаги, которые могут завершиться ошибкой
     * @param options.includeUrl — добавить URL страницы в сообщение об ошибке
     * @returns результат выполнения `action`
     */
    async executeWithErrorCheck(actionDescription, action, options) {
        const errorOptions = { actionDescription, ...options };
        try {
            const result = await action();
            await this.throwIfErrorsFound(errorOptions);
            return result;
        }
        catch (error) {
            await this.throwIfErrorsFound(errorOptions);
            throw error;
        }
    }
    /**
     * Проверяет отсутствие toast-ошибок на странице.
     * @param logContext — контекст для логирования
     */
    async assertNoErrors(logContext) {
        await test_1.test.step('Проверка отсутствия ошибок', async () => {
            await this.throwIfErrorsFound({ includeUrl: true });
            logger_1.logger.debug('Уведомления об ошибках отсутствуют', `${logContext}.assertNoErrorMessages`);
        });
    }
    async checkSuccessMessage(message) {
        await test_1.test.step(`Проверка сообщения об успешном выполнении "${message}"`, async () => {
            const expectedMessage = notification_messages_1.SUCCESS_MESSAGES[message];
            if (!expectedMessage) {
                throw new Error(`Сообщение "${message}" не найдено в SUCCESS_MESSAGES`);
            }
            const notification = this.page
                .getByTestId('notification_success')
                .filter({
                hasText: new RegExp(`Успешно?\\s*${expectedMessage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`),
            })
                .first();
            await (0, test_1.expect)(notification).toBeVisible({ timeout: (0, timeouts_1.getTimeouts)().EXPECT });
        });
    }
}
exports.UiNotificationService = UiNotificationService;
